/*
 * 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>

#ifdef USE_IN_LIBIO
# include <wchar.h>
# include <libio/iolibio.h>
#endif

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 = INTUSE(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;
}

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 (INTUSE(svc_sendreply) (transp_l, (xdrproc_t)INTUSE(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))
	  {
	    INTUSE(svcerr_decode) (transp_l);
	    return;
	  }
	outdata = (*(pl->p_progname)) (xdrbuf);
	if (outdata == NULL && pl->p_outproc != (xdrproc_t)INTUSE(xdr_void))
	  /* there was an error */
	  return;
	if (!INTUSE(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);
}
