/* Parts of this file are derived from the original Sun (ONC) RPC
 * code, under the following copyright:
 */
/*
 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
 * unrestricted use provided that this legend is included on all tape
 * media and as a part of the software program in whole or part.  Users
 * may copy or modify Sun RPC without charge, but are not authorized
 * to license or distribute it to anyone else except as part of a product or
 * program developed by the user.
 *
 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
 *
 * Sun RPC is provided with no support and without any obligation on the
 * part of Sun Microsystems, Inc. to assist in its use, correction,
 * modification or enhancement.
 *
 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
 * OR ANY PART THEREOF.
 *
 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
 * or profits or other special, indirect and consequential damages, even if
 * Sun has been advised of the possibility of such damages.
 *
 * Sun Microsystems, Inc.
 * 2550 Garcia Avenue
 * Mountain View, California  94043
 */
/*
 * svc.c, Server-side remote procedure call interface.
 *
 * There are two sets of procedures here.  The xprt routines are
 * for handling transport handles.  The svc routines handle the
 * list of service routines.
 *
 * Copyright (C) 1984, Sun Microsystems, Inc.
 */

#include <rpc/rpc.h>
#include <sys/select.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <rpc/rpc_router_ioctl.h>
#include <debug.h>
#include <pthread.h>

extern XDR *xdr_init_common(const char *name, int is_client);
extern void xdr_destroy_common(XDR *xdr);
extern int r_control(int handle, const uint32 cmd, void *arg);

#include <stdio.h>
#include <errno.h>
#include <string.h>

typedef struct registered_server_struct {
    /* MUST BE AT OFFSET ZERO!  The client code assumes this when it overwrites
       the XDR for server entries which represent a callback client.  Those
       server entries do not have their own XDRs.
    */
    XDR *xdr;
    /* Because the xdr is NULL for callback clients (as opposed to true
       servers), we keep track of the program number and version number in this
       structure as well.
    */       
    rpcprog_t x_prog; /* program number */
    rpcvers_t x_vers; /* program version */

    int active;
    struct registered_server_struct *next;
    SVCXPRT *xprt;
    __dispatch_fn_t dispatch;
} registered_server;

struct SVCXPRT {
    fd_set fdset;
    int max_fd;
    pthread_attr_t thread_attr;
    pthread_t  svc_thread;
    pthread_mutexattr_t lock_attr;
    pthread_mutex_t lock;
    registered_server *servers;
    volatile int num_servers;
};

static pthread_mutex_t xprt_lock = PTHREAD_MUTEX_INITIALIZER;
int xprt_refcount;
SVCXPRT *the_xprt; /* FIXME: have a list or something */

/*
  This routine is only of interest if a service implementor does not
  call svc_run(), but instead implements custom asynchronous event
  processing.  It is called when the select() system call has
  determined that an RPC request has arrived on some RPC socket(s);
  rdfds is the resultant read file descriptor bit mask.  The routine
  returns when all sockets associated with the value of rdfds have
  been serviced.
 */

void svc_dispatch(registered_server *svc, SVCXPRT *xprt);

static void* svc_context(void *__u)
{
    SVCXPRT *xprt = (SVCXPRT *)__u;
    int n;
    struct timeval tv;
    volatile fd_set rfds;
    while(xprt->num_servers) {
        rfds = xprt->fdset;
        tv.tv_sec = 1; tv.tv_usec = 0;
        n = select(xprt->max_fd + 1, (fd_set *)&rfds, NULL, NULL, &tv);
        if (n < 0) {
            E("select() error %s (%d)\n", strerror(errno), errno);
            continue;
        }
        if (n) {
            for (n = 0; n <= xprt->max_fd; n++) {
                if (FD_ISSET(n, &rfds)) {
                    /* the file descriptor points to the service instance; we
                       simply look that service by its file descriptor, and
                       call its service function. */
                    registered_server *trav = xprt->servers;
                    for (; trav; trav = trav->next)
                        if (trav->xdr->fd == n) {
                            /* read the entire RPC */
                            trav->xdr->xops->read(trav->xdr);
                            svc_dispatch(trav, xprt);
                            break;
                        }
                } /* if fd is set */
            } /* for each fd */
        }
    }
    D("RPC-server thread exiting!\n");
    return NULL;
}

SVCXPRT *svcrtr_create (void)
{
    SVCXPRT *xprt;
    pthread_mutex_lock(&xprt_lock);
    if (the_xprt) {
        D("The RPC transport has already been created.\n");
        xprt = the_xprt;
    } else {
        xprt = calloc(1, sizeof(SVCXPRT));
        if (xprt) {
            FD_ZERO(&xprt->fdset);
            xprt->max_fd = 0;
            pthread_attr_init(&xprt->thread_attr);
            pthread_attr_setdetachstate(&xprt->thread_attr,
                                        PTHREAD_CREATE_DETACHED);
            pthread_mutexattr_init(&xprt->lock_attr);
//          pthread_mutexattr_settype(&xprt->lock_attr,
//                                    PTHREAD_MUTEX_RECURSIVE);
            pthread_mutex_init(&xprt->lock, &xprt->lock_attr);
        }
    }    
    pthread_mutex_unlock(&xprt_lock);
    return xprt;
}

void svc_destroy(SVCXPRT *xprt)
{
    /* the last call to xprt_unregister() does the job */
}

/* NOTE: this function must always be called with the xprt->lock held! */
static registered_server* svc_find_nosync(SVCXPRT *xprt, 
                                          rpcprog_t prog, rpcvers_t vers,
                                          registered_server **prev)
{
    registered_server *trav;
    trav = xprt->servers;
    if (prev) *prev = NULL;
    for (; trav; trav = trav->next) {
        if (trav->x_prog == prog && trav->x_vers == vers)
            break;
        if (prev) *prev = trav;
    }
    return trav;
}

registered_server* svc_find(SVCXPRT *xprt, 
                            rpcprog_t prog, rpcvers_t vers)
{
    pthread_mutex_lock(&xprt->lock);
    registered_server *svc = svc_find_nosync(xprt, prog, vers, NULL);
    pthread_mutex_unlock(&xprt->lock);
    return svc;
}

bool_t svc_register (SVCXPRT *xprt, rpcprog_t prog, rpcvers_t vers, 
                     __dispatch_fn_t dispatch,
                     rpcprot_t protocol)
{
    struct rpcrouter_ioctl_server_args args;
    registered_server* svc;

    pthread_mutex_lock(&xprt->lock);

    D("registering for service %08x:%d\n", (uint32_t)prog, (int)vers);

    svc = svc_find_nosync(xprt, prog, vers, NULL);

    if (svc) {
        E("service is already registered!\n");
        pthread_mutex_unlock(&xprt->lock);
        return svc->dispatch == dispatch;
    }

    svc = malloc(sizeof(registered_server));

    /* If the program number of the RPC server ANDs with 0x01000000, then it is
       not a true RPC server, but a callback client for an existing RPC client.
       For example, if you have an RPC client with the program number
       0x30000000, then its callback client will have a program number
       0x31000000.  RPC calls on program number 0x31000000 will arrive on the
       RPC client 0x30000000.
    */

    if (prog & 0x01000000) {
        D("RPC server %08x:%d is a callback client, "
          "creating dummy service entry!\n", (uint32_t)prog, (int)vers);
        svc->xdr = NULL;
        svc->x_prog = prog;
        svc->x_vers = vers;        
    } else {
        V("RPC server %08x:%d is a real server.\n", (uint32_t)prog, (int)vers);
        svc->xdr = xdr_init_common("/dev/oncrpc/00000000:0",
                                   0 /* not a client XDR */);
        if (svc->xdr == NULL) {
            E("failed to initialize service (permissions?)!\n");
            free(svc);
            pthread_mutex_unlock(&xprt->lock);
            return FALSE;
        }

        args.prog = prog;
        args.vers = vers;    
        V("RPC server %08x:%d: registering with kernel.\n",
          (uint32_t)prog, (int)vers);
        if (r_control(svc->xdr->fd, 
                      RPC_ROUTER_IOCTL_REGISTER_SERVER, 
                      &args) < 0) {
            E("ioctl(RPC_ROUTER_IOCTL_REGISTER_SERVER) failed: %s!\n",
              strerror(errno));
            xdr_destroy_common(svc->xdr);
            free(svc);
            pthread_mutex_unlock(&xprt->lock);
            return FALSE;
        }

        FD_SET(svc->xdr->fd, &xprt->fdset);
        if (svc->xdr->fd > xprt->max_fd) xprt->max_fd = svc->xdr->fd;
        svc->x_prog = svc->xdr->x_prog = prog;
        svc->x_vers = svc->xdr->x_vers = vers;        
    }

    svc->dispatch = dispatch;
    svc->next = xprt->servers;
    xprt->servers = svc;
    xprt->num_servers++;
    V("RPC server %08x:%d: after registering, there are %d servers.\n",
      (uint32_t)prog, (int)vers, xprt->num_servers);
    svc->xprt = xprt;
    if (xprt->num_servers == 1) {
        D("creating RPC-server thread (detached)!\n");
        pthread_create(&xprt->svc_thread,
                       &xprt->thread_attr,
                       svc_context, xprt);
    }
    pthread_mutex_unlock(&xprt->lock);
    return TRUE;
}

void svc_unregister (SVCXPRT *xprt, rpcprog_t prog, rpcvers_t vers) {
    registered_server *prev, *found;
    pthread_mutex_lock(&xprt->lock);
    found = svc_find_nosync(xprt, prog, vers, &prev);
    D("unregistering RPC server %08x:%d\n", (unsigned)prog, (unsigned)vers);
    if (found) {
        struct rpcrouter_ioctl_server_args args;
        if (prev) {
            V("RPC server %08x:%d is not the first in the list\n", 
              (unsigned)prog, (unsigned)vers);
            prev->next = found->next;
        } else {
            V("RPC server %08x:%d the first in the list\n", 
              (unsigned)prog, (unsigned)vers);
            xprt->servers = found->next;
        }

        /* Is is an RPC server or a callback client? */
        if (found->xdr) {
            if (!(prog & 0x01000000)) {
                V("RPC server %08x:%d is not a callback server.\n",
                  (unsigned)prog, (unsigned)vers);
                /* don't bother decreasing the xprt->max_fd to the previous
                 * minimum.
                 */
                args.prog = prog;
                args.vers = vers;    
                if (r_control(found->xdr->fd,
                              RPC_ROUTER_IOCTL_UNREGISTER_SERVER,
                              &args) < 0) {
                    E("ioctl(RPC_ROUTER_IOCTL_UNREGISTER_SERVER) "
                      "failed: %s!\n", 
                      strerror(errno));
                }                
                FD_CLR(found->xdr->fd, &xprt->fdset);
            }
            V("RPC server %08x:%d: destroying XDR\n",
                   (unsigned)prog, (unsigned)vers);
            xdr_destroy_common(found->xdr);
        }
        else V("RPC server %08x:%d does not have an associated XDR\n", 
               (unsigned)prog, (unsigned)vers);

        free(found);
        /* When this goes to zero, the RPC-server thread will exit.  We do not
         * need to wait for the thread to exit, because it is detached.
         */
        xprt->num_servers--;
        V("RPC server %08x:%d: after unregistering, %d servers left.\n",
          (unsigned)prog, (unsigned)vers, xprt->num_servers);
    }
    pthread_mutex_unlock(&xprt->lock);
}

/* 
RPC_OFFSET + 
0  00000000 RPC xid                 network-byte order
1  00000000 RPC call 
2  00000002 rpc version
3  3000005d prog num
4  00000000 prog vers
5  00000001 proc num

6  00000000 cred
7  00000000 cred
8  00000000 verf
9  00000000 verf

a  0001fcc1 parms...
b  00354230 
c  00000000
 */

void svc_dispatch(registered_server *svc, SVCXPRT *xprt)
{
    struct svc_req req;

    /* Read enough of the packet to be able to find the program number, the
       program-version number, and the procedure call.  Notice that anything
       arriving on this channel must be an RPC call.  Also, the program and
       program-version numbers must match what's in the XDR of the service. */

    D("reading on fd %d for %08x:%d\n", 
      svc->xdr->fd, svc->x_prog, svc->x_vers);

    uint32 prog = ntohl(((uint32 *)(svc->xdr->in_msg))[RPC_OFFSET+3]);
    uint32 vers = ntohl(((uint32 *)(svc->xdr->in_msg))[RPC_OFFSET+4]);
    uint32 proc = ntohl(((uint32 *)(svc->xdr->in_msg))[RPC_OFFSET+5]);

    if (ntohl(((uint32 *)svc->xdr->in_msg)[RPC_OFFSET+1]) != RPC_MSG_CALL) {
        E("ERROR: expecting an RPC call on server channel!\n");
        return;
    }

    if (prog != svc->x_prog) {
        E("ERROR: prog num %08x does not match expected %08x!\n",
          (unsigned)prog, (unsigned)svc->x_prog);
        return;
    }

    if (vers != svc->xdr->x_vers) {
        E("ERROR: prog vers %08x does not match expected %08x!\n",
                vers, svc->xdr->x_vers);
        return;
    }

    req.rq_prog = prog;
    req.rq_vers = vers;
    req.rq_proc = proc;
    req.rq_xprt = xprt;

    D("START: SVC DISPATCH %08x:%08x --> %08x\n",
      (uint32_t)prog, (int)vers, proc);
    /* The RPC header (XID, call type, RPC version, program number, program
       version, proc number) is 6 long words; the default credentials are 4
       long words.  This the offset (RPC_OFFSET + 10)<<2 is where the first
       arguments start.
    */
    svc->xdr->in_next = (RPC_OFFSET + 6 + 4)*sizeof(uint32); 

    svc->active = getpid();
    svc->xdr->x_op = XDR_DECODE;
    svc->dispatch(&req, (SVCXPRT *)svc);
    svc->active = 0;
    D("DONE: SVC DISPATCH %08x:%08x --> %08x\n",
      (uint32_t)prog, (int)vers, proc);
}

void xprt_register(SVCXPRT *xprt)
{
    pthread_mutex_lock(&xprt_lock);
    if (!the_xprt || (xprt && (xprt == the_xprt))) {
        xprt_refcount++;
        the_xprt = xprt;
        D("registering RPC transport (refcount %d)\n", xprt_refcount);
    }
    else E("a different RPC transport has already been registered!\n");
    pthread_mutex_unlock(&xprt_lock);
}

void xprt_unregister (SVCXPRT *xprt)
{
    pthread_mutex_lock(&xprt_lock);
    if (xprt && xprt == the_xprt) {
        if (xprt_refcount == 1) {
            xprt_refcount = 0;
            D("Destroying RPC transport (servers %d)\n",
              the_xprt->num_servers);

            pthread_attr_destroy(&xprt->thread_attr);
            pthread_mutexattr_destroy(&xprt->lock_attr);
            pthread_mutex_destroy(&xprt->lock);
            /* Make sure the thread has existed before we free the xprt
               structure.  The thread is created as detached, so we do not wait
               for it after we set the terminate flag in svc_unregister, but we
               do have to wait for it to exit when we call svc_destroy.
            */
            pthread_join(xprt->svc_thread, NULL);
            free(xprt);
            the_xprt = NULL;
        }
        else xprt_refcount--;
        D("unregistering RPC transport (refcount %d)\n", xprt_refcount);
    }
    else E("no RPC transport has been registered!\n");
    pthread_mutex_unlock(&xprt_lock);
}

/* The functions that follow all take a pointer to the SVCXPRT instead of the
   XDR of the server that they refer to.  The xprt pointer is actually a 
   pointer to a registered_server, which identified the RPC server in
   question.
*/

bool_t svc_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
{
    registered_server *serv = (registered_server *)xprt;
    if (serv->active) {
        bool_t result = (bool_t) (*xdr_args)(serv->xdr, args_ptr);            
        XDR_MSG_DONE (serv->xdr);
        return result;
    }
    return FALSE;
} /* svc_getargs */

bool_t svc_freeargs (SVCXPRT * xprt, xdrproc_t xdr_args, caddr_t args_ptr)
{
    registered_server *serv = (registered_server *)xprt;
    if (serv->active) { 
        serv->xdr->x_op = XDR_FREE;
        return (*xdr_args)((XDR *)serv->xdr, args_ptr);
    }
    return FALSE;
}

/* Send a reply to an rpc request */
bool_t
svc_sendreply (SVCXPRT *xprt, xdrproc_t xdr_results,
               caddr_t xdr_location)
{
    registered_server *serv = (registered_server *)xprt;
    if (serv->active) { 
        opaque_auth verf; 
        verf.oa_flavor = AUTH_NONE;
        verf.oa_length = 0;
        
        serv->xdr->x_op = XDR_ENCODE;
        
        if (!xdr_reply_msg_start(serv->xdr, &verf) ||
            !xdr_results(serv->xdr, xdr_location)) 
            return FALSE;

        ((uint32 *)(serv->xdr->out_msg))[RPC_OFFSET] =
            ((uint32 *)(serv->xdr->in_msg))[RPC_OFFSET]; //RPC xid
        D("%08x:%d sending RPC reply (XID %d)\n",
          serv->xdr->x_prog,
          serv->xdr->x_vers,
          ntohl(((uint32 *)(serv->xdr->out_msg))[RPC_OFFSET]));
        XDR_MSG_SEND(serv->xdr);
        return TRUE;
    }
    return FALSE;
}

/* Service error functions. */

#define SVCERR_XDR_SEND(xdr, reply) \
  ( XDR_MSG_START(xdr, RPC_MSG_REPLY) && \
    xdr_send_reply_header(xdr, &reply) && \
    XDR_MSG_SEND(xdr) )

void svcerr_decode (SVCXPRT *xprt)
{
    registered_server *serv = (registered_server *)xprt;
    if (serv->active) { 
        rpc_reply_header reply;
        reply.stat = RPC_MSG_ACCEPTED;
        reply.u.ar.verf = serv->xdr->verf;
        reply.u.ar.stat = RPC_GARBAGE_ARGS;
        
        if (!SVCERR_XDR_SEND(serv->xdr, reply))
            /* Couldn't send the reply - just give up */
            XDR_MSG_ABORT(serv->xdr);
    }
} /* svcerr_decode */

void svcerr_systemerr (SVCXPRT *xprt)
{
    registered_server *serv = (registered_server *)xprt;
    if (serv->active) { 
        rpc_reply_header reply;
        reply.stat = RPC_MSG_ACCEPTED;
        reply.u.ar.verf = serv->xdr->verf;
        reply.u.ar.stat = RPC_SYSTEM_ERR;
        
        if (!SVCERR_XDR_SEND(serv->xdr, reply))
            /* Couldn't send the reply - just give up */
            XDR_MSG_ABORT(serv->xdr);
    }
} /* svcerr_systemerr */

void svcerr_noproc(SVCXPRT *xprt)
{
    registered_server *serv = (registered_server *)xprt;
    if (serv->active) { 
        rpc_reply_header reply;        
        reply.stat = RPC_MSG_ACCEPTED;
        reply.u.ar.verf = serv->xdr->verf;
        reply.u.ar.stat = RPC_PROC_UNAVAIL;
        
        if (!SVCERR_XDR_SEND(serv->xdr, reply))
            /* Couldn't send the reply - just give up */
            XDR_MSG_ABORT(serv->xdr);        
    }
} /* svcerr_noproc */
