* Copyright (C) 1995, 1997-1999 Jeffrey A. Uphoff
* Modified by Olaf Kirch, Oct. 1996.
* Modified by H.J. Lu, 1998.
+ * Modified by L. Hohberger of Mission Critical Linux, 2000.
*
* NSM for Linux.
*/
#include "statd.h"
#include "version.h"
+/* Socket operations */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+
short int restart = 0;
int _rpcpmstart = 0; /* flags for tirpc rpcgen */
int _rpcfdtype = 0;
int _rpcsvcdirty = 0;
+int run_mode = 0; /* foreground logging mode */
+
+/* LH - I had these local to main, but it seemed silly to have
+ * two copies of each - one in main(), one static in log.c...
+ * It also eliminates the 256-char static in log.c */
+char *name_p = NULL;
+char *version_p = NULL;
extern void sm_prog_1 (struct svc_req *, register SVCXPRT *);
#ifdef HAVE_TCP_WRAPPER
#include "tcpwrapper.h"
-static void
+static void
sm_prog_1_wrapper (struct svc_req *rqstp, register SVCXPRT *transp)
{
- /* remote host authorization check */
- if (!check_default("statd", svc_getcaller(transp),
- rqstp->rq_proc, SM_PROG)) {
- svcerr_auth (transp, AUTH_FAILED);
- return;
- }
-
- sm_prog_1 (rqstp, transp);
+ /* remote host authorization check */
+ if (!check_default("statd", svc_getcaller(transp),
+ rqstp->rq_proc, SM_PROG)) {
+ svcerr_auth (transp, AUTH_FAILED);
+ return;
+ }
+
+ sm_prog_1 (rqstp, transp);
}
#define sm_prog_1 sm_prog_1_wrapper
static void
killer (int sig)
{
- log (L_FATAL, "Caught signal %d, un-registering and exiting.", sig);
- pmap_unset (SM_PROG, SM_VERS);
- exit (0);
+ log (L_FATAL, "Caught signal %d, un-registering and exiting.", sig);
+ pmap_unset (SM_PROG, SM_VERS);
+ exit (0);
+}
+
+/*
+ * Startup information.
+ */
+static void log_modes(void)
+{
+ char buf[128]; /* watch stack size... */
+
+ /* No flags = no message */
+ if (!run_mode) return;
+
+ memset(buf,0,128);
+ sprintf(buf,"Flags: ");
+ if (run_mode & MODE_NODAEMON)
+ strcat(buf,"No-Daemon ");
+ if (run_mode & MODE_LOG_STDERR)
+ strcat(buf,"Log-STDERR ");
+ /* future: IP aliasing
+ if (run_mode & MODE_NOTIFY_ONLY)
+ {
+ strcat(buf,"Notify-Only ");
+ } */
+ log(L_WARNING,buf);
+ /* future: IP aliasing
+ if (run_mode & MODE_NOTIFY_ONLY)
+ {
+ dprintf(L_DEBUG,"Notify IP: %s",svr_addr);
+ } */
}
+/*
+ * Since we do more than standard statd stuff, we might need to
+ * help the occasional admin.
+ */
+static void
+usage()
+{
+ fprintf(stderr,"usage: %s [options]\n", name_p);
+ fprintf(stderr," -h, -? Print this help screen.\n");
+ fprintf(stderr," -F Foreground (no-daemon mode)\n");
+ fprintf(stderr," -d Verbose logging to stderr. Foreground mode only.\n");
+ fprintf(stderr," -V Display version information and exit.\n");
+}
/*
* Entry routine/main loop.
*/
-int
-main (int argc, char **argv)
+int main (int argc, char **argv)
{
- int pid;
- int foreground = 0;
-
- log_init (argv[0]);
-
- if (argc == 2 && strcmp (argv [1], "-F") == 0) {
- foreground = 1;
- argc--;
- argv++;
- }
+ extern char *optarg;
+ int pid;
+ char arg;
+
+ /* Default: daemon mode, no other options */
+ run_mode = 0;
+
+ /* Set the basename */
+ if ((name_p = strrchr(argv[0],'/')) != NULL) {
+ name_p ++;
+ } else {
+ name_p = argv[0];
+ }
+
+ /* Get the version */
+ if ((version_p = strrchr(VERSION,' ')) != NULL) {
+ version_p++;
+ } else {
+ version_p = VERSION;
+ }
+
+ /* Process command line switches */
+ while ((arg = getopt(argc, argv, "h?VFd")) >= 0) {
+ switch (arg) {
+ case 'V': /* Version */
+ printf("%s version %s\n",name_p,version_p);
+ exit(0);
+ case 'F': /* Foreground/nodaemon mode */
+ run_mode |= MODE_NODAEMON;
+ break;
+ case 'd': /* No daemon only - log to stderr */
+ run_mode |= MODE_LOG_STDERR;
+ break;
+ case '?': /* heeeeeelllllllpppp? heh */
+ case 'h':
+ usage();
+ exit (0);
+ default: /* oh dear ... heh */
+ usage();
+ exit(-1);
+ }
+ }
+
+ if (!(run_mode & MODE_NODAEMON)) {
+ run_mode &= ~MODE_LOG_STDERR; /* Never log to console in
+ daemon mode. */
+ }
+
+ log_init (name_p,version_p);
+
+ log_modes();
#ifdef SIMULATIONS
- if (argc > 1)
- simulator (--argc, ++argv); /* simulator() does exit() */
+ if (argc > 1)
+ /* LH - I _really_ need to update simulator... */
+ simulator (--argc, ++argv); /* simulator() does exit() */
#endif
-
- if (!foreground) {
- int filedes;
-
- if ((pid = fork ()) < 0) {
- perror ("Could not fork");
- exit (1);
- } else if (pid != 0) {
- /* Parent. */
- exit (0);
- }
- /* Child. */
- setsid ();
- chdir (DIR_BASE);
-
- for (filedes = 0; filedes < sysconf (_SC_OPEN_MAX); filedes++) {
- close (filedes);
- }
- }
-
- /* Child. */
- signal (SIGHUP, killer);
- signal (SIGINT, killer);
- signal (SIGTERM, killer);
- /* WARNING: the following works on Linux and SysV, but not BSD! */
- signal(SIGCHLD, SIG_IGN);
-
- for (;;) {
- pmap_unset (SM_PROG, SM_VERS);
- change_state ();
- shuffle_dirs ();
- notify_hosts ();
- ++restart;
- do_regist (SM_PROG, sm_prog_1);
- my_svc_run (); /* I rolled my own, Olaf made it better... */
- }
- return 0;
+
+ if (!(run_mode & MODE_NODAEMON)) {
+ int filedes;
+
+ if ((pid = fork ()) < 0) {
+ perror ("Could not fork");
+ exit (1);
+ } else if (pid != 0) {
+ /* Parent. */
+ exit (0);
+ }
+ /* Child. */
+ setsid ();
+ chdir (DIR_BASE);
+
+ for (filedes = 0; filedes < sysconf (_SC_OPEN_MAX); filedes++) {
+ close (filedes);
+ }
+ }
+
+ /* Child. */
+ signal (SIGHUP, killer);
+ signal (SIGINT, killer);
+ signal (SIGTERM, killer);
+ /* WARNING: the following works on Linux and SysV, but not BSD! */
+ signal(SIGCHLD, SIG_IGN);
+
+ for (;;) {
+ pmap_unset (SM_PROG, SM_VERS);
+ change_state ();
+ shuffle_dirs (); /* Move directory names around */
+ notify_hosts (); /* Send out notify requests */
+ ++restart;
+
+ /* future: IP aliasing
+ if (!(run_mode & MODE_NOTIFY_ONLY)) {
+ do_regist (SM_PROG, sm_prog_1);
+ } */
+ do_regist(SM_PROG,sm_prog_1);
+
+ /*
+ * Handle incoming requests: SM_NOTIFY socket requests, as
+ * well as callbacks from lockd.
+ */
+ my_svc_run(); /* I rolled my own, Olaf made it better... */
+ }
+ return 0;
}
/*
* Register services.
*/
-void
-do_regist(u_long prog, void (*sm_prog_1)())
-/* do_regist(u_long prog, __dispatch_fn_t sm_prog_1) */
+void do_regist(u_long prog, void (*sm_prog_1)())
{
- SVCXPRT *transp;
+ SVCXPRT *transp;
- if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL)
- die("cannot create udp service.");
+ if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL)
+ die("cannot create udp service.");
- if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_UDP))
- die("unable to register (SM_PROG, SM_VERS, udp).");
+ if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_UDP))
+ die("unable to register (SM_PROG, SM_VERS, udp).");
- if ((transp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL)
- die("cannot create tcp service.");
+ if ((transp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL)
+ die("cannot create tcp service.");
- if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_TCP))
- die("unable to register (SM_PROG, SM_VERS, tcp).");
+ if (!svc_register(transp, prog, SM_VERS, sm_prog_1, IPPROTO_TCP))
+ die("unable to register (SM_PROG, SM_VERS, tcp).");
}