+ extern char *optarg;
+ int pid;
+ int arg;
+ int port = 0, out_port = 0;
+ struct rlimit rlim;
+
+ int pipefds[2] = { -1, -1};
+ char status;
+
+ /* 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;
+ }
+
+ /* Set hostname */
+ MY_NAME = NULL;
+
+ /* Process command line switches */
+ while ((arg = getopt_long(argc, argv, "h?vVFNH:dn:p:o:P:L", longopts, NULL)) != EOF) {
+ switch (arg) {
+ case 'V': /* Version */
+ case 'v':
+ printf("%s version %s\n",name_p,version_p);
+ exit(0);
+ case 'F': /* Foreground/nodaemon mode */
+ run_mode |= MODE_NODAEMON;
+ break;
+ case 'N':
+ run_mode |= MODE_NOTIFY_ONLY;
+ break;
+ case 'L': /* Listen only */
+ run_mode |= MODE_NO_NOTIFY;
+ break;
+ case 'd': /* No daemon only - log to stderr */
+ run_mode |= MODE_LOG_STDERR;
+ break;
+ case 'o':
+ out_port = atoi(optarg);
+ if (out_port < 1 || out_port > 65535) {
+ fprintf(stderr, "%s: bad port number: %s\n",
+ argv[0], optarg);
+ usage();
+ exit(1);
+ }
+ break;
+ case 'p':
+ port = atoi(optarg);
+ if (port < 1 || port > 65535) {
+ fprintf(stderr, "%s: bad port number: %s\n",
+ argv[0], optarg);
+ usage();
+ exit(1);
+ }
+ break;
+ case 'n': /* Specify local hostname */
+ run_mode |= STATIC_HOSTNAME;
+ MY_NAME = xstrdup(optarg);
+ break;
+ case 'P':
+
+ if ((DIR_BASE = xstrdup(optarg)) == NULL) {
+ fprintf(stderr, "%s: xstrdup(%s) failed!\n",
+ argv[0], optarg);
+ exit(1);
+ }
+
+ SM_DIR = xmalloc(strlen(DIR_BASE) + 1 + sizeof("sm"));
+ SM_BAK_DIR = xmalloc(strlen(DIR_BASE) + 1 + sizeof("sm.bak"));
+ SM_STAT_PATH = xmalloc(strlen(DIR_BASE) + 1 + sizeof("state"));
+
+ if ((SM_DIR == NULL)
+ || (SM_BAK_DIR == NULL)
+ || (SM_STAT_PATH == NULL)) {
+
+ fprintf(stderr, "%s: xmalloc() failed!\n",
+ argv[0]);
+ exit(1);
+ }
+ if (DIR_BASE[strlen(DIR_BASE)-1] == '/') {
+ sprintf(SM_DIR, "%ssm", DIR_BASE );
+ sprintf(SM_BAK_DIR, "%ssm.bak", DIR_BASE );
+ sprintf(SM_STAT_PATH, "%sstate", DIR_BASE );
+ } else {
+ sprintf(SM_DIR, "%s/sm", DIR_BASE );
+ sprintf(SM_BAK_DIR, "%s/sm.bak", DIR_BASE );
+ sprintf(SM_STAT_PATH, "%s/state", DIR_BASE );
+ }
+ break;
+ case 'H': /* PRC: specify the ha-callout program */
+ if ((ha_callout_prog = xstrdup(optarg)) == NULL) {
+ fprintf(stderr, "%s: xstrdup(%s) failed!\n",
+ argv[0], optarg);
+ exit(1);
+ }
+ break;
+ case '?': /* heeeeeelllllllpppp? heh */
+ case 'h':
+ usage();
+ exit (0);
+ default: /* oh dear ... heh */
+ usage();
+ exit(-1);
+ }
+ }
+
+ if (port == out_port && port != 0) {
+ fprintf(stderr, "Listening and outgoing ports cannot be the same!\n");
+ exit(-1);
+ }
+
+ if (run_mode & MODE_NOTIFY_ONLY) {
+ fprintf(stderr, "%s: -N deprecated, consider using /usr/sbin/sm-notify directly\n",
+ name_p);
+ run_sm_notify(out_port);
+ }
+
+
+ if (!(run_mode & MODE_NODAEMON)) {
+ run_mode &= ~MODE_LOG_STDERR; /* Never log to console in
+ daemon mode. */
+ }