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