clnt_simp.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. #include <alloca.h>
  35. #include <errno.h>
  36. #include <stdio.h>
  37. #include <unistd.h>
  38. #include <rpc/rpc.h>
  39. #include <sys/socket.h>
  40. #include <netdb.h>
  41. #include <string.h>
  42. #include <shlib-compat.h>
  43. struct callrpc_private_s
  44. {
  45. CLIENT *client;
  46. int socket;
  47. u_long oldprognum, oldversnum, valid;
  48. char *oldhost;
  49. };
  50. #define callrpc_private RPC_THREAD_VARIABLE(callrpc_private_s)
  51. int
  52. callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
  53. xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out)
  54. {
  55. struct callrpc_private_s *crp = callrpc_private;
  56. struct sockaddr_in server_addr;
  57. enum clnt_stat clnt_stat;
  58. struct timeval timeout, tottimeout;
  59. if (crp == 0)
  60. {
  61. crp = (struct callrpc_private_s *) calloc (1, sizeof (*crp));
  62. if (crp == 0)
  63. return 0;
  64. callrpc_private = crp;
  65. }
  66. if (crp->oldhost == NULL)
  67. {
  68. crp->oldhost = malloc (256);
  69. crp->oldhost[0] = 0;
  70. crp->socket = RPC_ANYSOCK;
  71. }
  72. if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
  73. && strcmp (crp->oldhost, host) == 0)
  74. {
  75. /* reuse old client */
  76. }
  77. else
  78. {
  79. crp->valid = 0;
  80. if (crp->socket != RPC_ANYSOCK)
  81. {
  82. (void) __close (crp->socket);
  83. crp->socket = RPC_ANYSOCK;
  84. }
  85. if (crp->client)
  86. {
  87. clnt_destroy (crp->client);
  88. crp->client = NULL;
  89. }
  90. if (__libc_rpc_gethostbyname (host, &server_addr) != 0)
  91. return (int) get_rpc_createerr().cf_stat;
  92. timeout.tv_usec = 0;
  93. timeout.tv_sec = 5;
  94. if ((crp->client = clntudp_create (&server_addr, (u_long) prognum,
  95. (u_long) versnum, timeout, &crp->socket)) == NULL)
  96. return (int) get_rpc_createerr().cf_stat;
  97. crp->valid = 1;
  98. crp->oldprognum = prognum;
  99. crp->oldversnum = versnum;
  100. (void) strncpy (crp->oldhost, host, 255);
  101. crp->oldhost[255] = '\0';
  102. }
  103. tottimeout.tv_sec = 25;
  104. tottimeout.tv_usec = 0;
  105. clnt_stat = clnt_call (crp->client, procnum, inproc, (char *) in,
  106. outproc, out, tottimeout);
  107. /*
  108. * if call failed, empty cache
  109. */
  110. if (clnt_stat != RPC_SUCCESS)
  111. crp->valid = 0;
  112. return (int) clnt_stat;
  113. }
  114. libc_hidden_nolink_sunrpc (callrpc, GLIBC_2_0)
  115. void
  116. __rpc_thread_clnt_cleanup (void)
  117. {
  118. struct callrpc_private_s *rcp = RPC_THREAD_VARIABLE(callrpc_private_s);
  119. if (rcp) {
  120. if (rcp->client)
  121. CLNT_DESTROY (rcp->client);
  122. free (rcp);
  123. }
  124. }