summaryrefslogtreecommitdiffstats
path: root/support/nfs/rpcdispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'support/nfs/rpcdispatch.c')
-rw-r--r--support/nfs/rpcdispatch.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/support/nfs/rpcdispatch.c b/support/nfs/rpcdispatch.c
new file mode 100644
index 0000000..7329f41
--- /dev/null
+++ b/support/nfs/rpcdispatch.c
@@ -0,0 +1,69 @@
+/*
+ * support/nfs/rcpdispatch.c
+ *
+ * Generic RPC dispatcher.
+ *
+ * Copyright (C) 1995, 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <signal.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <string.h>
+#include "rpcmisc.h"
+#include "xlog.h"
+
+void
+rpc_dispatch(struct svc_req *rqstp, SVCXPRT *transp,
+ struct rpc_dtable *dtable, int nvers,
+ void *argp, void *resp)
+{
+ struct rpc_dentry *dent;
+ int rq_vers = (int)rqstp->rq_vers;
+
+ if (rq_vers < 1 || rq_vers > nvers) {
+ svcerr_progvers(transp, 1, nvers);
+ return;
+ }
+ dtable += (rq_vers - 1);
+ if (rqstp->rq_proc > dtable->nproc) {
+ svcerr_noproc(transp);
+ return;
+ }
+
+ if (dtable->nproc <= rqstp->rq_proc) {
+ svcerr_noproc(transp);
+ return;
+ }
+
+ dent = dtable->entries + rqstp->rq_proc;
+
+ if (dent->func == NULL) {
+ svcerr_noproc(transp);
+ return;
+ }
+
+ memset(argp, 0, dent->xdr_arg_size);
+ memset(resp, 0, dent->xdr_res_size);
+
+ if (!svc_getargs(transp, dent->xdr_arg_fn, argp)) {
+ svcerr_decode(transp);
+ return;
+ }
+
+ if ((dent->func)(rqstp, argp, resp) && resp != 0) {
+ if (!svc_sendreply(transp, dent->xdr_res_fn, (caddr_t)resp))
+ svcerr_systemerr(transp);
+ }
+ if (!svc_freeargs(transp, dent->xdr_arg_fn, argp)) {
+ xlog(L_ERROR, "failed to free RPC arguments");
+ exit (2);
+ }
+}