svc_simple.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * svc_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 <stdio.h>
  35. #include <string.h>
  36. #include <libintl.h>
  37. #include <unistd.h>
  38. #include <rpc/rpc.h>
  39. #include <rpc/pmap_clnt.h>
  40. #include <sys/socket.h>
  41. #include <netdb.h>
  42. #include <wchar.h>
  43. #include <libio/iolibio.h>
  44. #include <shlib-compat.h>
  45. struct proglst_
  46. {
  47. char *(*p_progname) (char *);
  48. int p_prognum;
  49. int p_procnum;
  50. xdrproc_t p_inproc, p_outproc;
  51. struct proglst_ *p_nxt;
  52. };
  53. #define proglst RPC_THREAD_VARIABLE(svcsimple_proglst_s)
  54. static void universal (struct svc_req *rqstp, SVCXPRT *transp_s);
  55. #define transp RPC_THREAD_VARIABLE(svcsimple_transp_s)
  56. int
  57. __registerrpc (u_long prognum, u_long versnum, u_long procnum,
  58. char *(*progname) (char *), xdrproc_t inproc, xdrproc_t outproc)
  59. {
  60. struct proglst_ *pl;
  61. char *buf;
  62. if (procnum == NULLPROC)
  63. {
  64. if (__asprintf (&buf, _("can't reassign procedure number %ld\n"),
  65. NULLPROC) < 0)
  66. buf = NULL;
  67. goto err_out;
  68. }
  69. if (transp == 0)
  70. {
  71. transp = svcudp_create (RPC_ANYSOCK);
  72. if (transp == NULL)
  73. {
  74. buf = __strdup (_("couldn't create an rpc server\n"));
  75. goto err_out;
  76. }
  77. }
  78. (void) pmap_unset ((u_long) prognum, (u_long) versnum);
  79. if (!svc_register (transp, (u_long) prognum, (u_long) versnum,
  80. universal, IPPROTO_UDP))
  81. {
  82. if (__asprintf (&buf, _("couldn't register prog %ld vers %ld\n"),
  83. prognum, versnum) < 0)
  84. buf = NULL;
  85. goto err_out;
  86. }
  87. pl = (struct proglst_ *) malloc (sizeof (struct proglst_));
  88. if (pl == NULL)
  89. {
  90. buf = __strdup (_("registerrpc: out of memory\n"));
  91. goto err_out;
  92. }
  93. pl->p_progname = progname;
  94. pl->p_prognum = prognum;
  95. pl->p_procnum = procnum;
  96. pl->p_inproc = inproc;
  97. pl->p_outproc = outproc;
  98. pl->p_nxt = proglst;
  99. proglst = pl;
  100. return 0;
  101. err_out:
  102. if (buf == NULL)
  103. return -1;
  104. (void) __fxprintf (NULL, "%s", buf);
  105. free (buf);
  106. return -1;
  107. }
  108. libc_sunrpc_symbol (__registerrpc, registerrpc, GLIBC_2_0)
  109. static void
  110. universal (struct svc_req *rqstp, SVCXPRT *transp_l)
  111. {
  112. int prog, proc;
  113. char *outdata;
  114. char xdrbuf[UDPMSGSIZE];
  115. struct proglst_ *pl;
  116. char *buf = NULL;
  117. /*
  118. * enforce "procnum 0 is echo" convention
  119. */
  120. if (rqstp->rq_proc == NULLPROC)
  121. {
  122. if (svc_sendreply (transp_l, (xdrproc_t)xdr_void,
  123. (char *) NULL) == FALSE)
  124. {
  125. __write (STDERR_FILENO, "xxx\n", 4);
  126. exit (1);
  127. }
  128. return;
  129. }
  130. prog = rqstp->rq_prog;
  131. proc = rqstp->rq_proc;
  132. for (pl = proglst; pl != NULL; pl = pl->p_nxt)
  133. if (pl->p_prognum == prog && pl->p_procnum == proc)
  134. {
  135. /* decode arguments into a CLEAN buffer */
  136. memset (xdrbuf, 0, sizeof (xdrbuf)); /* required ! */
  137. if (!svc_getargs (transp_l, pl->p_inproc, xdrbuf))
  138. {
  139. svcerr_decode (transp_l);
  140. return;
  141. }
  142. outdata = (*(pl->p_progname)) (xdrbuf);
  143. if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void)
  144. /* there was an error */
  145. return;
  146. if (!svc_sendreply (transp_l, pl->p_outproc, outdata))
  147. {
  148. if (__asprintf (&buf, _("trouble replying to prog %d\n"),
  149. pl->p_prognum) < 0)
  150. buf = NULL;
  151. goto err_out2;
  152. }
  153. /* free the decoded arguments */
  154. (void) svc_freeargs (transp_l, pl->p_inproc, xdrbuf);
  155. return;
  156. }
  157. if (__asprintf (&buf, _("never registered prog %d\n"), prog) < 0)
  158. buf = NULL;
  159. err_out2:
  160. if (buf == NULL)
  161. exit (1);
  162. __fxprintf (NULL, "%s", buf);
  163. free (buf);
  164. exit (1);
  165. }