Initial revision
[nfs-utils.git] / support / nfs / rpcdispatch.c
1 /*
2  * support/nfs/rcpdispatch.c
3  *
4  * Generic RPC dispatcher.
5  *
6  * Copyright (C) 1995, 1996, Olaf Kirch <okir@monad.swb.de>
7  */
8
9 #include "config.h"
10
11 #include <stdio.h>
12 #include <rpc/rpc.h>
13 #include <rpc/pmap_clnt.h>
14 #include <signal.h>
15 #include <arpa/inet.h>
16 #include <netdb.h>
17 #include <string.h>
18 #include "rpcmisc.h"
19 #include "xlog.h"
20
21 void
22 rpc_dispatch(struct svc_req *rqstp, SVCXPRT *transp,
23                         struct rpc_dtable *dtable, int nvers,
24                         void *argp, void *resp)
25 {
26         struct rpc_dentry       *dent;
27
28         if (rqstp->rq_vers > nvers) {
29                 svcerr_progvers(transp, 1, nvers);
30                 return;
31         }
32         dtable += (rqstp->rq_vers - 1);
33         if (rqstp->rq_proc > dtable->nproc) {
34                 svcerr_noproc(transp);
35                 return;
36         }
37
38         dent = dtable->entries + rqstp->rq_proc;
39
40         if (dent->func == NULL) {
41                 svcerr_noproc(transp);
42                 return;
43         }
44
45         memset(argp, 0, dent->xdr_arg_size);
46         memset(resp, 0, dent->xdr_res_size);
47
48         if (!svc_getargs(transp, dent->xdr_arg_fn, argp)) {
49                 svcerr_decode(transp);
50                 return;
51         }
52
53         if ((dent->func)(rqstp, argp, resp) && resp != 0) {
54                 if (!svc_sendreply(transp, dent->xdr_res_fn, (caddr_t)resp)) 
55                         svcerr_systemerr(transp);
56         }
57         if (!svc_freeargs(transp, dent->xdr_arg_fn, argp)) {
58                 xlog(L_ERROR, "failed to free RPC arguments");
59                 exit (2);
60         }
61 }
62
63 #if 0
64 /*
65  * This is our replacement for svc_run. It turns off some signals while
66  * executing the server procedures to avoid nasty race conditions.
67  */
68 void
69 rpc_svcrun(fd_set *morefds, void (*func)(int fd))
70 {
71         sigset_t        block, current;
72         fd_set          readfds;
73
74         for (;;) {
75                 readfds = svc_fdset;
76                 if (morefds) {
77                         int     i;
78
79                         /* most efficient */
80                         for (i = 0; i < FD_SETSIZE; i++)
81                                 if (FD_ISSET(i, morefds))
82                                         FD_SET(i, &readfs);
83                 }
84                 switch (select(FD_SETSIZE, &readfds, NULL, NULL, NULL)) {
85                 case -1:
86                         if (errno == EINTR)
87                                 continue;
88                         xlog(L_ERROR, "svc_run: - select failed");
89                         break;
90                 case 0:
91                         continue;
92                 default:
93                         if (morefds) {
94                                 int     i;
95
96                                 /* most efficient */
97                                 for (i = 0; i < FD_SETSIZE; i++)
98                                         if (FD_ISSET(i, morefds) &&
99                                             FD_ISSET(i, &readfds))
100                                                 func(i);
101                         }
102                         sigemptyset(&block);
103                         sigaddset(&block, SIGALRM);
104                         sigaddset(&block, SIGVTALRM);
105                         sigaddset(&block, SIGIO);
106                         sigprocmask(SIG_BLOCK, &block, &current);
107                         svc_getreqset(&readfds);
108                         sigprocmask(SIG_SETMASK, &current, NULL);
109                 }
110         }
111 }
112 #endif