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