(root)/
glibc-2.38/
sunrpc/
clnt_gen.c
       1  /*
       2   * Copyright (c) 2010, Oracle America, Inc.
       3   *
       4   * Redistribution and use in source and binary forms, with or without
       5   * modification, are permitted provided that the following conditions are
       6   * met:
       7   *
       8   *     * Redistributions of source code must retain the above copyright
       9   *       notice, this list of conditions and the following disclaimer.
      10   *     * Redistributions in binary form must reproduce the above
      11   *       copyright notice, this list of conditions and the following
      12   *       disclaimer in the documentation and/or other materials
      13   *       provided with the distribution.
      14   *     * Neither the name of the "Oracle America, Inc." nor the names of its
      15   *       contributors may be used to endorse or promote products derived
      16   *       from this software without specific prior written permission.
      17   *
      18   *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      19   *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      20   *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
      21   *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
      22   *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
      23   *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      24   *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
      25   *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      26   *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      27   *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      28   *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      29   *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30   */
      31  
      32  #include <alloca.h>
      33  #include <errno.h>
      34  #include <string.h>
      35  #include <rpc/rpc.h>
      36  #include <sys/socket.h>
      37  #include <netdb.h>
      38  #include <shlib-compat.h>
      39  
      40  /*
      41   * Generic client creation: takes (hostname, program-number, protocol) and
      42   * returns client handle. Default options are set, which the user can
      43   * change using the rpc equivalent of ioctl()'s.
      44   */
      45  CLIENT *
      46  clnt_create (const char *hostname, u_long prog, u_long vers,
      47  	     const char *proto)
      48  {
      49    struct protoent protobuf, *p;
      50    size_t prtbuflen;
      51    char *prttmpbuf;
      52    struct sockaddr_in sin;
      53    struct sockaddr_un sun;
      54    int sock;
      55    struct timeval tv;
      56    CLIENT *client;
      57  
      58    if (strcmp (proto, "unix") == 0)
      59      {
      60        if (__sockaddr_un_set (&sun, hostname) < 0)
      61  	{
      62  	  struct rpc_createerr *ce = &get_rpc_createerr ();
      63  	  ce->cf_stat = RPC_SYSTEMERROR;
      64  	  ce->cf_error.re_errno = errno;
      65  	  return NULL;
      66  	}
      67        sock = RPC_ANYSOCK;
      68        client = clntunix_create (&sun, prog, vers, &sock, 0, 0);
      69        if (client == NULL)
      70  	return NULL;
      71  #if 0
      72        /* This is not wanted.  This would disable the user from having
      73  	 a timeout in the clnt_call() call.  Only a call to cnlt_control()
      74  	 by the user should set the timeout value.  */
      75        tv.tv_sec = 25;
      76        tv.tv_usec = 0;
      77        clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
      78  #endif
      79        return client;
      80      }
      81  
      82    if (__libc_rpc_gethostbyname (hostname, &sin) != 0)
      83      return NULL;
      84  
      85    prtbuflen = 1024;
      86    prttmpbuf = __alloca (prtbuflen);
      87    while (__getprotobyname_r (proto, &protobuf, prttmpbuf, prtbuflen, &p) != 0
      88  	 || p == NULL)
      89      if (errno != ERANGE)
      90        {
      91  	struct rpc_createerr *ce = &get_rpc_createerr ();
      92  	ce->cf_stat = RPC_UNKNOWNPROTO;
      93  	ce->cf_error.re_errno = EPFNOSUPPORT;
      94  	return NULL;
      95        }
      96      else
      97        {
      98  	/* Enlarge the buffer.  */
      99  	prtbuflen *= 2;
     100  	prttmpbuf = __alloca (prtbuflen);
     101        }
     102  
     103    sock = RPC_ANYSOCK;
     104    switch (p->p_proto)
     105      {
     106      case IPPROTO_UDP:
     107        tv.tv_sec = 5;
     108        tv.tv_usec = 0;
     109        client = clntudp_create (&sin, prog, vers, tv, &sock);
     110        if (client == NULL)
     111  	{
     112  	  return NULL;
     113  	}
     114  #if 0
     115        /* This is not wanted.  This would disable the user from having
     116  	 a timeout in the clnt_call() call.  Only a call to cnlt_control()
     117  	 by the user should set the timeout value.  */
     118        tv.tv_sec = 25;
     119        clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
     120  #endif
     121        break;
     122      case IPPROTO_TCP:
     123        client = clnttcp_create (&sin, prog, vers, &sock, 0, 0);
     124        if (client == NULL)
     125  	{
     126  	  return NULL;
     127  	}
     128  #if 0
     129        /* This is not wanted.  This would disable the user from having
     130  	 a timeout in the clnt_call() call.  Only a call to cnlt_control()
     131  	 by the user should set the timeout value.  */
     132        tv.tv_sec = 25;
     133        tv.tv_usec = 0;
     134        clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
     135  #endif
     136        break;
     137      default:
     138        {
     139  	struct rpc_createerr *ce = &get_rpc_createerr ();
     140  	ce->cf_stat = RPC_SYSTEMERROR;
     141  	ce->cf_error.re_errno = EPFNOSUPPORT;
     142        }
     143        return (NULL);
     144      }
     145    return client;
     146  }
     147  #ifdef EXPORT_RPC_SYMBOLS
     148  libc_hidden_def (clnt_create)
     149  #else
     150  libc_hidden_nolink_sunrpc (clnt_create, GLIBC_2_0)
     151  #endif