/*
 * svc_simple.c
 * Simplified front end to rpc.
 *
 * Copyright (c) 2010, Oracle America, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials
 *       provided with the distribution.
 *     * Neither the name of the "Oracle America, Inc." nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <string.h>
#include <libintl.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
#include <sys/socket.h>
#include <netdb.h>

#include <wchar.h>
#include <libio/iolibio.h>
#include <shlib-compat.h>

struct proglst_
  {
    char *(*p_progname) (char *);
    int p_prognum;
    int p_procnum;
    xdrproc_t p_inproc, p_outproc;
    struct proglst_ *p_nxt;
  };
#ifdef _RPC_THREAD_SAFE_
#define proglst RPC_THREAD_VARIABLE(svcsimple_proglst_s)
#else
static struct proglst_ *proglst;
#endif


static void universal (struct svc_req *rqstp, SVCXPRT *transp_s);
#ifdef _RPC_THREAD_SAFE_
#define transp RPC_THREAD_VARIABLE(svcsimple_transp_s)
#else
static SVCXPRT *transp;
#endif

int
__registerrpc (u_long prognum, u_long versnum, u_long procnum,
	       char *(*progname) (char *), xdrproc_t inproc, xdrproc_t outproc)
{
  struct proglst_ *pl;
  char *buf;

  if (procnum == NULLPROC)
    {

      if (__asprintf (&buf, _("can't reassign procedure number %ld\n"),
		      NULLPROC) < 0)
	buf = NULL;
      goto err_out;
    }
  if (transp == 0)
    {
      transp = svcudp_create (RPC_ANYSOCK);
      if (transp == NULL)
	{
	  buf = strdup (_("couldn't create an rpc server\n"));
	  goto err_out;
	}
    }
  (void) pmap_unset ((u_long) prognum, (u_long) versnum);
  if (!svc_register (transp, (u_long) prognum, (u_long) versnum,
		     universal, IPPROTO_UDP))
    {
      if (__asprintf (&buf, _("couldn't register prog %ld vers %ld\n"),
		      prognum, versnum) < 0)
	buf = NULL;
      goto err_out;
    }
  pl = (struct proglst_ *) malloc (sizeof (struct proglst_));
  if (pl == NULL)
    {
      buf = strdup (_("registerrpc: out of memory\n"));
      goto err_out;
    }
  pl->p_progname = progname;
  pl->p_prognum = prognum;
  pl->p_procnum = procnum;
  pl->p_inproc = inproc;
  pl->p_outproc = outproc;
  pl->p_nxt = proglst;
  proglst = pl;
  return 0;

 err_out:
  if (buf == NULL)
    return -1;
  (void) __fxprintf (NULL, "%s", buf);
  free (buf);
  return -1;
}

libc_sunrpc_symbol (__registerrpc, registerrpc, GLIBC_2_0)


static void
universal (struct svc_req *rqstp, SVCXPRT *transp_l)
{
  int prog, proc;
  char *outdata;
  char xdrbuf[UDPMSGSIZE];
  struct proglst_ *pl;
  char *buf = NULL;

  /*
   * enforce "procnum 0 is echo" convention
   */
  if (rqstp->rq_proc == NULLPROC)
    {
      if (svc_sendreply (transp_l, (xdrproc_t)xdr_void,
			 (char *) NULL) == FALSE)
	{
	  __write (STDERR_FILENO, "xxx\n", 4);
	  exit (1);
	}
      return;
    }
  prog = rqstp->rq_prog;
  proc = rqstp->rq_proc;
  for (pl = proglst; pl != NULL; pl = pl->p_nxt)
    if (pl->p_prognum == prog && pl->p_procnum == proc)
      {
	/* decode arguments into a CLEAN buffer */
	__bzero (xdrbuf, sizeof (xdrbuf));	/* required ! */
	if (!svc_getargs (transp_l, pl->p_inproc, xdrbuf))
	  {
	    svcerr_decode (transp_l);
	    return;
	  }
	outdata = (*(pl->p_progname)) (xdrbuf);
	if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void)
	  /* there was an error */
	  return;
	if (!svc_sendreply (transp_l, pl->p_outproc, outdata))
	  {
	    if (__asprintf (&buf, _("trouble replying to prog %d\n"),
			    pl->p_prognum) < 0)
	      buf = NULL;
	    goto err_out2;
	  }
	/* free the decoded arguments */
	(void) svc_freeargs (transp_l, pl->p_inproc, xdrbuf);
	return;
      }
  if (__asprintf (&buf, _("never registered prog %d\n"), prog) < 0)
    buf = NULL;
 err_out2:
  if (buf == NULL)
    exit (1);
  __fxprintf (NULL, "%s", buf);
  free (buf);
  exit (1);
}
