2000-08-25 H.J. Lu <hjl@lucon.org>
[nfs-utils.git] / utils / statd / statd.c
1 /* 
2  * Copyright (C) 1995, 1997-1999 Jeffrey A. Uphoff
3  * Modified by Olaf Kirch, Oct. 1996.
4  * Modified by H.J. Lu, 1998.
5  *
6  * NSM for Linux.
7  */
8
9 #include "config.h"
10 #include <limits.h>
11 #include <signal.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <rpc/rpc.h>
15 #include <rpc/pmap_clnt.h>
16 #include "statd.h"
17 #include "version.h"
18
19 short int restart = 0;
20 int     _rpcpmstart = 0;        /* flags for tirpc rpcgen */
21 int     _rpcfdtype = 0;
22 int     _rpcsvcdirty = 0;
23
24 extern void sm_prog_1 (struct svc_req *, register SVCXPRT *);
25
26 #ifdef SIMULATIONS
27 extern void simulator (int, char **);
28 #endif
29
30
31 #ifdef HAVE_TCP_WRAPPER 
32 #include "tcpwrapper.h"
33
34 static void
35 sm_prog_1_wrapper (struct svc_req *rqstp, register SVCXPRT *transp)
36 {
37   /* remote host authorization check */
38   if (!check_default("statd", svc_getcaller(transp),
39                      rqstp->rq_proc, (u_long) 0)) {
40     svcerr_auth (transp, AUTH_FAILED);
41     return;
42   }
43
44   sm_prog_1 (rqstp, transp);
45 }
46
47 #define sm_prog_1 sm_prog_1_wrapper
48 #endif
49
50 /*
51  * Signal handler.
52  */
53 static void 
54 killer (int sig)
55 {
56   log (L_FATAL, "Caught signal %d, un-registering and exiting.", sig);
57   pmap_unset (SM_PROG, SM_VERS);
58   exit (0);
59 }
60
61
62 /* 
63  * Entry routine/main loop.
64  */
65 int
66 main (int argc, char **argv)
67 {
68   int pid;
69   int foreground = 0;
70
71   log_init (argv[0]);
72
73   if (argc == 2 && strcmp (argv [1], "-F") == 0) {
74     foreground = 1;
75     argc--;
76     argv++;
77   }
78
79 #ifdef SIMULATIONS
80   if (argc > 1)
81     simulator (--argc, ++argv); /* simulator() does exit() */
82 #endif
83   
84   if (!foreground) {
85     int filedes;
86
87     if ((pid = fork ()) < 0) {
88       perror ("Could not fork");
89       exit (1);
90     } else if (pid != 0) {
91       /* Parent. */
92       exit (0);
93     }
94     /* Child.  */
95     setsid ();
96     chdir (DIR_BASE);
97
98     for (filedes = 0; filedes < sysconf (_SC_OPEN_MAX); filedes++) {
99       close (filedes);
100     }
101   }
102
103   /* Child. */
104   signal (SIGHUP, killer);
105   signal (SIGINT, killer);
106   signal (SIGTERM, killer);
107
108   for (;;) {
109     pmap_unset (SM_PROG, SM_VERS);
110     change_state ();
111     shuffle_dirs ();
112     notify_hosts ();
113     ++restart;
114     do_regist (SM_PROG, sm_prog_1);
115     my_svc_run ();              /* I rolled my own, Olaf made it better... */
116   }
117   return 0;
118 }
119
120
121 /*
122  * Register services.
123  */
124 void
125 do_regist(u_long prog, void (*sm_prog_1)())
126 /* do_regist(u_long prog, __dispatch_fn_t sm_prog_1) */
127 {
128   SVCXPRT        *transp;
129
130   if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL)
131     die("cannot create udp service.");
132
133   if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_UDP))
134     die("unable to register (SM_PROG, SM_VERS, udp).");
135
136   if ((transp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL)
137     die("cannot create tcp service.");
138
139   if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_TCP))
140     die("unable to register (SM_PROG, SM_VERS, tcp).");
141 }