18360efbdSAlfred Perlstein /* $NetBSD: clnt_simple.c,v 1.21 2000/07/06 03:10:34 christos Exp $ */ 28360efbdSAlfred Perlstein 399064799SGarrett Wollman /* 499064799SGarrett Wollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 599064799SGarrett Wollman * unrestricted use provided that this legend is included on all tape 699064799SGarrett Wollman * media and as a part of the software program in whole or part. Users 799064799SGarrett Wollman * may copy or modify Sun RPC without charge, but are not authorized 899064799SGarrett Wollman * to license or distribute it to anyone else except as part of a product or 999064799SGarrett Wollman * program developed by the user. 1099064799SGarrett Wollman * 1199064799SGarrett Wollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1299064799SGarrett Wollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1399064799SGarrett Wollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1499064799SGarrett Wollman * 1599064799SGarrett Wollman * Sun RPC is provided with no support and without any obligation on the 1699064799SGarrett Wollman * part of Sun Microsystems, Inc. to assist in its use, correction, 1799064799SGarrett Wollman * modification or enhancement. 1899064799SGarrett Wollman * 1999064799SGarrett Wollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 2099064799SGarrett Wollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2199064799SGarrett Wollman * OR ANY PART THEREOF. 2299064799SGarrett Wollman * 2399064799SGarrett Wollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2499064799SGarrett Wollman * or profits or other special, indirect and consequential damages, even if 2599064799SGarrett Wollman * Sun has been advised of the possibility of such damages. 2699064799SGarrett Wollman * 2799064799SGarrett Wollman * Sun Microsystems, Inc. 2899064799SGarrett Wollman * 2550 Garcia Avenue 2999064799SGarrett Wollman * Mountain View, California 94043 3099064799SGarrett Wollman */ 318360efbdSAlfred Perlstein /* 328360efbdSAlfred Perlstein * Copyright (c) 1986-1991 by Sun Microsystems Inc. 338360efbdSAlfred Perlstein */ 3499064799SGarrett Wollman 3599064799SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint) 3699064799SGarrett Wollman /*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/ 3799064799SGarrett Wollman /*static char *sccsid = "from: @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC";*/ 387f3dea24SPeter Wemm static char *rcsid = "$FreeBSD$"; 3999064799SGarrett Wollman #endif 4099064799SGarrett Wollman 4199064799SGarrett Wollman /* 4299064799SGarrett Wollman * clnt_simple.c 438360efbdSAlfred Perlstein * Simplified front end to client rpc. 4499064799SGarrett Wollman * 4599064799SGarrett Wollman */ 4699064799SGarrett Wollman 47d201fe46SDaniel Eischen #include "namespace.h" 489f5afc13SIan Dowse #include "reentrant.h" 490ab74c6fSPeter Wemm #include <sys/param.h> 5099064799SGarrett Wollman #include <stdio.h> 518360efbdSAlfred Perlstein #include <errno.h> 5299064799SGarrett Wollman #include <rpc/rpc.h> 538360efbdSAlfred Perlstein #include <string.h> 548360efbdSAlfred Perlstein #include <stdlib.h> 558360efbdSAlfred Perlstein #include <fcntl.h> 568360efbdSAlfred Perlstein #include <unistd.h> 57d201fe46SDaniel Eischen #include "un-namespace.h" 5899064799SGarrett Wollman 598360efbdSAlfred Perlstein #ifndef MAXHOSTNAMELEN 608360efbdSAlfred Perlstein #define MAXHOSTNAMELEN 64 618360efbdSAlfred Perlstein #endif 6299064799SGarrett Wollman 638360efbdSAlfred Perlstein #ifndef NETIDLEN 648360efbdSAlfred Perlstein #define NETIDLEN 32 658360efbdSAlfred Perlstein #endif 668360efbdSAlfred Perlstein 678360efbdSAlfred Perlstein struct rpc_call_private { 688360efbdSAlfred Perlstein int valid; /* Is this entry valid ? */ 698360efbdSAlfred Perlstein CLIENT *client; /* Client handle */ 708360efbdSAlfred Perlstein pid_t pid; /* process-id at moment of creation */ 718360efbdSAlfred Perlstein rpcprog_t prognum; /* Program */ 728360efbdSAlfred Perlstein rpcvers_t versnum; /* Version */ 738360efbdSAlfred Perlstein char host[MAXHOSTNAMELEN]; /* Servers host */ 748360efbdSAlfred Perlstein char nettype[NETIDLEN]; /* Network type */ 758360efbdSAlfred Perlstein }; 768360efbdSAlfred Perlstein static struct rpc_call_private *rpc_call_private_main; 778360efbdSAlfred Perlstein 788360efbdSAlfred Perlstein static void rpc_call_destroy __P((void *)); 798360efbdSAlfred Perlstein 808360efbdSAlfred Perlstein static void 818360efbdSAlfred Perlstein rpc_call_destroy(void *vp) 8299064799SGarrett Wollman { 838360efbdSAlfred Perlstein struct rpc_call_private *rcp = (struct rpc_call_private *)vp; 8499064799SGarrett Wollman 858360efbdSAlfred Perlstein if (rcp) { 868360efbdSAlfred Perlstein if (rcp->client) 878360efbdSAlfred Perlstein CLNT_DESTROY(rcp->client); 888360efbdSAlfred Perlstein free(rcp); 8999064799SGarrett Wollman } 9099064799SGarrett Wollman } 918360efbdSAlfred Perlstein 928360efbdSAlfred Perlstein /* 938360efbdSAlfred Perlstein * This is the simplified interface to the client rpc layer. 948360efbdSAlfred Perlstein * The client handle is not destroyed here and is reused for 958360efbdSAlfred Perlstein * the future calls to same prog, vers, host and nettype combination. 968360efbdSAlfred Perlstein * 978360efbdSAlfred Perlstein * The total time available is 25 seconds. 988360efbdSAlfred Perlstein */ 998360efbdSAlfred Perlstein enum clnt_stat 1008360efbdSAlfred Perlstein rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype) 1018360efbdSAlfred Perlstein const char *host; /* host name */ 1028360efbdSAlfred Perlstein rpcprog_t prognum; /* program number */ 1038360efbdSAlfred Perlstein rpcvers_t versnum; /* version number */ 1048360efbdSAlfred Perlstein rpcproc_t procnum; /* procedure number */ 1058360efbdSAlfred Perlstein xdrproc_t inproc, outproc; /* in/out XDR procedures */ 1068360efbdSAlfred Perlstein const char *in; 1078360efbdSAlfred Perlstein char *out; /* recv/send data */ 1088360efbdSAlfred Perlstein const char *nettype; /* nettype */ 1098360efbdSAlfred Perlstein { 1108360efbdSAlfred Perlstein struct rpc_call_private *rcp = (struct rpc_call_private *) 0; 1118360efbdSAlfred Perlstein enum clnt_stat clnt_stat; 1128360efbdSAlfred Perlstein struct timeval timeout, tottimeout; 1138360efbdSAlfred Perlstein static thread_key_t rpc_call_key; 1148360efbdSAlfred Perlstein extern mutex_t tsd_lock; 1158360efbdSAlfred Perlstein int main_thread = 1; 1168360efbdSAlfred Perlstein 1178360efbdSAlfred Perlstein if ((main_thread = thr_main())) { 1188360efbdSAlfred Perlstein rcp = rpc_call_private_main; 11999064799SGarrett Wollman } else { 1208360efbdSAlfred Perlstein if (rpc_call_key == 0) { 1218360efbdSAlfred Perlstein mutex_lock(&tsd_lock); 1228360efbdSAlfred Perlstein if (rpc_call_key == 0) 1238360efbdSAlfred Perlstein thr_keycreate(&rpc_call_key, rpc_call_destroy); 1248360efbdSAlfred Perlstein mutex_unlock(&tsd_lock); 12599064799SGarrett Wollman } 1268360efbdSAlfred Perlstein rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key); 1278360efbdSAlfred Perlstein } 1288360efbdSAlfred Perlstein if (rcp == NULL) { 1298360efbdSAlfred Perlstein rcp = malloc(sizeof (*rcp)); 1308360efbdSAlfred Perlstein if (rcp == NULL) { 1318360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_SYSTEMERROR; 1328360efbdSAlfred Perlstein rpc_createerr.cf_error.re_errno = errno; 1338360efbdSAlfred Perlstein return (rpc_createerr.cf_stat); 1348360efbdSAlfred Perlstein } 1358360efbdSAlfred Perlstein if (main_thread) 1368360efbdSAlfred Perlstein rpc_call_private_main = rcp; 1378360efbdSAlfred Perlstein else 1388360efbdSAlfred Perlstein thr_setspecific(rpc_call_key, (void *) rcp); 1398360efbdSAlfred Perlstein rcp->valid = 0; 1408360efbdSAlfred Perlstein rcp->client = NULL; 1418360efbdSAlfred Perlstein } 1428360efbdSAlfred Perlstein if ((nettype == NULL) || (nettype[0] == NULL)) 1438360efbdSAlfred Perlstein nettype = "netpath"; 1448360efbdSAlfred Perlstein if (!(rcp->valid && rcp->pid == getpid() && 1458360efbdSAlfred Perlstein (rcp->prognum == prognum) && 1468360efbdSAlfred Perlstein (rcp->versnum == versnum) && 1478360efbdSAlfred Perlstein (!strcmp(rcp->host, host)) && 1488360efbdSAlfred Perlstein (!strcmp(rcp->nettype, nettype)))) { 1498360efbdSAlfred Perlstein int fd; 1508360efbdSAlfred Perlstein 1518360efbdSAlfred Perlstein rcp->valid = 0; 1528360efbdSAlfred Perlstein if (rcp->client) 1538360efbdSAlfred Perlstein CLNT_DESTROY(rcp->client); 1548360efbdSAlfred Perlstein /* 1558360efbdSAlfred Perlstein * Using the first successful transport for that type 1568360efbdSAlfred Perlstein */ 1578360efbdSAlfred Perlstein rcp->client = clnt_create(host, prognum, versnum, nettype); 1588360efbdSAlfred Perlstein rcp->pid = getpid(); 1598360efbdSAlfred Perlstein if (rcp->client == NULL) { 1608360efbdSAlfred Perlstein return (rpc_createerr.cf_stat); 1618360efbdSAlfred Perlstein } 1628360efbdSAlfred Perlstein /* 1638360efbdSAlfred Perlstein * Set time outs for connectionless case. Do it 1648360efbdSAlfred Perlstein * unconditionally. Faster than doing a t_getinfo() 1658360efbdSAlfred Perlstein * and then doing the right thing. 1668360efbdSAlfred Perlstein */ 16799064799SGarrett Wollman timeout.tv_usec = 0; 16899064799SGarrett Wollman timeout.tv_sec = 5; 1698360efbdSAlfred Perlstein (void) CLNT_CONTROL(rcp->client, 1708360efbdSAlfred Perlstein CLSET_RETRY_TIMEOUT, (char *)(void *)&timeout); 1718360efbdSAlfred Perlstein if (CLNT_CONTROL(rcp->client, CLGET_FD, (char *)(void *)&fd)) 1728360efbdSAlfred Perlstein _fcntl(fd, F_SETFD, 1); /* make it "close on exec" */ 1738360efbdSAlfred Perlstein rcp->prognum = prognum; 1748360efbdSAlfred Perlstein rcp->versnum = versnum; 1758360efbdSAlfred Perlstein if ((strlen(host) < (size_t)MAXHOSTNAMELEN) && 1768360efbdSAlfred Perlstein (strlen(nettype) < (size_t)NETIDLEN)) { 1778360efbdSAlfred Perlstein (void) strcpy(rcp->host, host); 1788360efbdSAlfred Perlstein (void) strcpy(rcp->nettype, nettype); 1798360efbdSAlfred Perlstein rcp->valid = 1; 1808360efbdSAlfred Perlstein } else { 1818360efbdSAlfred Perlstein rcp->valid = 0; 18299064799SGarrett Wollman } 1838360efbdSAlfred Perlstein } /* else reuse old client */ 18499064799SGarrett Wollman tottimeout.tv_sec = 25; 18599064799SGarrett Wollman tottimeout.tv_usec = 0; 1868360efbdSAlfred Perlstein /*LINTED const castaway*/ 1878360efbdSAlfred Perlstein clnt_stat = CLNT_CALL(rcp->client, procnum, inproc, (char *) in, 18899064799SGarrett Wollman outproc, out, tottimeout); 18999064799SGarrett Wollman /* 19099064799SGarrett Wollman * if call failed, empty cache 19199064799SGarrett Wollman */ 19299064799SGarrett Wollman if (clnt_stat != RPC_SUCCESS) 1938360efbdSAlfred Perlstein rcp->valid = 0; 1948360efbdSAlfred Perlstein return (clnt_stat); 19599064799SGarrett Wollman } 196