Initial revision
[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 /*
32  * Signal handler.
33  */
34 static void 
35 killer (int sig)
36 {
37   log (L_FATAL, "Caught signal %d, un-registering and exiting.", sig);
38   pmap_unset (SM_PROG, SM_VERS);
39   exit (0);
40 }
41
42
43 /* 
44  * Entry routine/main loop.
45  */
46 int
47 main (int argc, char **argv)
48 {
49   int pid;
50   int foreground = 0;
51
52   log_init (argv[0]);
53
54   if (argc == 2 && strcmp (argv [1], "-F") == 0) {
55     foreground = 1;
56     argc--;
57     argv++;
58   }
59
60 #ifdef SIMULATIONS
61   if (argc > 1)
62     simulator (--argc, ++argv); /* simulator() does exit() */
63 #endif
64   
65   if (!foreground) {
66     int filedes;
67
68     if ((pid = fork ()) < 0) {
69       perror ("Could not fork");
70       exit (1);
71     } else if (pid != 0) {
72       /* Parent. */
73       exit (0);
74     }
75     /* Child.  */
76     setsid ();
77     chdir (DIR_BASE);
78
79     for (filedes = 0; filedes < OPEN_MAX; filedes++) {
80       close (filedes);
81     }
82   }
83
84   /* Child. */
85   signal (SIGHUP, killer);
86   signal (SIGINT, killer);
87   signal (SIGTERM, killer);
88
89   for (;;) {
90     pmap_unset (SM_PROG, SM_VERS);
91     change_state ();
92     shuffle_dirs ();
93     notify_hosts ();
94     ++restart;
95     do_regist (SM_PROG, sm_prog_1);
96     my_svc_run ();              /* I rolled my own, Olaf made it better... */
97   }
98   return 0;
99 }
100
101
102 /*
103  * Register services.
104  */
105 void
106 do_regist(u_long prog, void (*sm_prog_1)())
107 /* do_regist(u_long prog, __dispatch_fn_t sm_prog_1) */
108 {
109   SVCXPRT        *transp;
110
111   if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL)
112     die("cannot create udp service.");
113
114   if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_UDP))
115     die("unable to register (SM_PROG, SM_VERS, udp).");
116
117   if ((transp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL)
118     die("cannot create tcp service.");
119
120   if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_TCP))
121     die("unable to register (SM_PROG, SM_VERS, tcp).");
122 }