]> git.decadent.org.uk Git - nfs-utils.git/blob - utils/statd/statd.c
Added some misc. command line options (-V -h -? -d).
[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  * Modified by L. Hohberger of Mission Critical Linux, 2000.
6  *
7  * NSM for Linux.
8  */
9
10 #include "config.h"
11 #include <limits.h>
12 #include <signal.h>
13 #include <unistd.h>
14 #include <string.h>
15 #include <rpc/rpc.h>
16 #include <rpc/pmap_clnt.h>
17 #include "statd.h"
18 #include "version.h"
19
20 /* Socket operations */
21 #include <sys/types.h>
22 #include <sys/socket.h>
23
24
25 short int restart = 0;
26 int     _rpcpmstart = 0;        /* flags for tirpc rpcgen */
27 int     _rpcfdtype = 0;
28 int     _rpcsvcdirty = 0;
29 int     run_mode = 0;           /* foreground logging mode */
30
31 /* LH - I had these local to main, but it seemed silly to have 
32  * two copies of each - one in main(), one static in log.c... 
33  * It also eliminates the 256-char static in log.c */
34 char *name_p = NULL;
35 char *version_p = NULL;
36
37 extern void sm_prog_1 (struct svc_req *, register SVCXPRT *);
38
39 #ifdef SIMULATIONS
40 extern void simulator (int, char **);
41 #endif
42
43
44 #ifdef HAVE_TCP_WRAPPER 
45 #include "tcpwrapper.h"
46
47 static void 
48 sm_prog_1_wrapper (struct svc_req *rqstp, register SVCXPRT *transp)
49 {
50         /* remote host authorization check */
51         if (!check_default("statd", svc_getcaller(transp),
52                                  rqstp->rq_proc, SM_PROG)) {
53                 svcerr_auth (transp, AUTH_FAILED);
54                 return;
55         }
56
57         sm_prog_1 (rqstp, transp);
58 }
59
60 #define sm_prog_1 sm_prog_1_wrapper
61 #endif
62
63 /*
64  * Signal handler.
65  */
66 static void 
67 killer (int sig)
68 {
69         log (L_FATAL, "Caught signal %d, un-registering and exiting.", sig);
70         pmap_unset (SM_PROG, SM_VERS);
71         exit (0);
72 }
73
74 /*
75  * Startup information.
76  */
77 static void log_modes(void)
78 {
79         char buf[128];          /* watch stack size... */
80
81         /* No flags = no message */
82         if (!run_mode) return;
83
84         memset(buf,0,128);
85         sprintf(buf,"Flags: ");
86         if (run_mode & MODE_NODAEMON)
87                 strcat(buf,"No-Daemon ");
88         if (run_mode & MODE_LOG_STDERR)
89                 strcat(buf,"Log-STDERR ");
90         /* future: IP aliasing
91         if (run_mode & MODE_NOTIFY_ONLY)
92         {
93                 strcat(buf,"Notify-Only ");
94         } */
95         log(L_WARNING,buf);
96         /* future: IP aliasing
97         if (run_mode & MODE_NOTIFY_ONLY)
98         {
99                 dprintf(L_DEBUG,"Notify IP: %s",svr_addr);
100         } */
101 }
102
103 /*
104  * Since we do more than standard statd stuff, we might need to
105  * help the occasional admin. 
106  */
107 static void 
108 usage()
109 {
110         fprintf(stderr,"usage: %s [options]\n", name_p);
111         fprintf(stderr,"      -h, -?       Print this help screen.\n");
112         fprintf(stderr,"      -F           Foreground (no-daemon mode)\n");
113         fprintf(stderr,"      -d           Verbose logging to stderr.  Foreground mode only.\n");
114         fprintf(stderr,"      -V           Display version information and exit.\n");
115 }
116
117 /* 
118  * Entry routine/main loop.
119  */
120 int main (int argc, char **argv)
121 {
122         extern char *optarg;
123         int pid;
124         char arg;
125         
126         /* Default: daemon mode, no other options */
127         run_mode = 0;
128
129         /* Set the basename */
130         if ((name_p = strrchr(argv[0],'/')) != NULL) {
131                 name_p ++;
132         } else {
133                 name_p = argv[0];
134         }
135
136         /* Get the version */
137         if ((version_p = strrchr(VERSION,' ')) != NULL) {
138                 version_p++;
139         } else {
140                 version_p = VERSION;
141         }
142         
143         /* Process command line switches */
144         while ((arg = getopt(argc, argv, "h?VFd")) >= 0) {
145                 switch (arg) {
146                         case 'V':       /* Version */
147                                 printf("%s version %s\n",name_p,version_p);
148                                 exit(0);
149                         case 'F':       /* Foreground/nodaemon mode */
150                                 run_mode |= MODE_NODAEMON;
151                                 break;
152                         case 'd':       /* No daemon only - log to stderr */
153                                 run_mode |= MODE_LOG_STDERR;
154                                 break;
155                         case '?':       /* heeeeeelllllllpppp? heh */
156                         case 'h':
157                                 usage();
158                                 exit (0);
159                         default:        /* oh dear ... heh */
160                                 usage();
161                                 exit(-1);
162                 }
163         }
164
165         if (!(run_mode & MODE_NODAEMON)) {
166                 run_mode &= ~MODE_LOG_STDERR;   /* Never log to console in
167                                                    daemon mode. */
168         }
169
170         log_init (name_p,version_p);
171
172         log_modes();
173
174 #ifdef SIMULATIONS
175         if (argc > 1)
176                 /* LH - I _really_ need to update simulator... */
177                 simulator (--argc, ++argv);     /* simulator() does exit() */
178 #endif
179         
180         if (!(run_mode & MODE_NODAEMON)) {
181                 int filedes;
182
183                 if ((pid = fork ()) < 0) {
184                         perror ("Could not fork");
185                         exit (1);
186                 } else if (pid != 0) {
187                         /* Parent. */
188                         exit (0);
189                 }
190                 /* Child.       */
191                 setsid ();
192                 chdir (DIR_BASE);
193
194                 for (filedes = 0; filedes < sysconf (_SC_OPEN_MAX); filedes++) {
195                         close (filedes);
196                 }
197         }
198
199         /* Child. */
200         signal (SIGHUP, killer);
201         signal (SIGINT, killer);
202         signal (SIGTERM, killer);
203         /* WARNING: the following works on Linux and SysV, but not BSD! */
204         signal(SIGCHLD, SIG_IGN);
205
206         for (;;) {
207                 pmap_unset (SM_PROG, SM_VERS);
208                 change_state ();
209                 shuffle_dirs ();        /* Move directory names around */
210                 notify_hosts ();        /* Send out notify requests */
211                 ++restart;
212
213                 /* future: IP aliasing 
214                 if (!(run_mode & MODE_NOTIFY_ONLY)) {
215                         do_regist (SM_PROG, sm_prog_1);
216                 } */
217                 do_regist(SM_PROG,sm_prog_1);
218
219                 /*
220                  * Handle incoming requests:  SM_NOTIFY socket requests, as
221                  * well as callbacks from lockd.
222                  */
223                 my_svc_run();   /* I rolled my own, Olaf made it better... */
224         }
225         return 0;
226 }
227
228
229 /*
230  * Register services.
231  */
232 void do_regist(u_long prog, void (*sm_prog_1)())
233 {
234         SVCXPRT         *transp;
235
236         if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL)
237                 die("cannot create udp service.");
238
239         if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_UDP))
240                 die("unable to register (SM_PROG, SM_VERS, udp).");
241
242         if ((transp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL)
243                 die("cannot create tcp service.");
244
245         if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_TCP))
246                 die("unable to register (SM_PROG, SM_VERS, tcp).");
247 }