Blame SOURCES/nuxwdog-1214838-systemd.patch

fc3346
Index: src/com/redhat/nuxwdog/wdsignals.h
fc3346
===================================================================
fc3346
--- src/com/redhat/nuxwdog/wdsignals.h	(revision 87)
fc3346
+++ src/com/redhat/nuxwdog/wdsignals.h	(revision 89)
fc3346
@@ -32,5 +32,6 @@
fc3346
 void watchdog_create_signal_handlers(void);
fc3346
 void watchdog_delete_signal_handlers(void);
fc3346
 void watchdog_wait_signal(void);
fc3346
+void disable_sigchld_for_one_signal(void);
fc3346
 
fc3346
 #endif /* _WDSIGNAL_H_ */
fc3346
Index: src/com/redhat/nuxwdog/watchdog.cpp
fc3346
===================================================================
fc3346
--- src/com/redhat/nuxwdog/watchdog.cpp	(revision 87)
fc3346
+++ src/com/redhat/nuxwdog/watchdog.cpp	(revision 89)
fc3346
@@ -570,7 +570,9 @@
fc3346
 				    watchdog_error(errstr);
fc3346
 				    // _watchdog_death = 1; ???
fc3346
 				}
fc3346
-				rv = watchdog_pwd_save(prompt, serial, pwd_result);
fc3346
+                                if (pwd_result != NULL) {
fc3346
+				    rv = watchdog_pwd_save(prompt, serial, pwd_result);
fc3346
+                                }
fc3346
 				// check error code??
fc3346
 			    }	// otherwise can fall through without prompting
fc3346
 			}
fc3346
Index: src/com/redhat/nuxwdog/wdpwd.cpp
fc3346
===================================================================
fc3346
--- src/com/redhat/nuxwdog/wdpwd.cpp	(revision 87)
fc3346
+++ src/com/redhat/nuxwdog/wdpwd.cpp	(revision 89)
fc3346
@@ -20,7 +20,9 @@
fc3346
 
fc3346
 #include <stdlib.h>
fc3346
 #include <unistd.h>
fc3346
+#include <sys/stat.h>
fc3346
 #include <sys/types.h>
fc3346
+#include <sys/wait.h>
fc3346
 #include <stdio.h>
fc3346
 #include <string.h>
fc3346
 #include <termios.h>
fc3346
@@ -27,6 +29,7 @@
fc3346
 #include <errno.h>
fc3346
 #include "config.h"
fc3346
 #include "wdlog.h"
fc3346
+#include "wdsignals.h"
fc3346
 
fc3346
 #ifdef USE_KEYRING
fc3346
 #include <sys/types.h>
fc3346
@@ -40,10 +43,10 @@
fc3346
 static void echoOff(int fd)
fc3346
 {
fc3346
     if (isatty(fd)) {
fc3346
-	struct termios tio;
fc3346
-	tcgetattr(fd, &tio;;
fc3346
-	tio.c_lflag &= ~ECHO;
fc3346
-	tcsetattr(fd, TCSAFLUSH, &tio;;
fc3346
+        struct termios tio;
fc3346
+        tcgetattr(fd, &tio;;
fc3346
+        tio.c_lflag &= ~ECHO;
fc3346
+        tcsetattr(fd, TCSAFLUSH, &tio;;
fc3346
     }
fc3346
 }
fc3346
 
fc3346
@@ -50,10 +53,10 @@
fc3346
 static void echoOn(int fd)
fc3346
 {
fc3346
     if (isatty(fd)) {
fc3346
-	struct termios tio;
fc3346
-	tcgetattr(fd, &tio;;
fc3346
-	tio.c_lflag |= ECHO;
fc3346
-	tcsetattr(fd, TCSAFLUSH, &tio;;
fc3346
+        struct termios tio;
fc3346
+        tcgetattr(fd, &tio;;
fc3346
+        tio.c_lflag |= ECHO;
fc3346
+        tcsetattr(fd, TCSAFLUSH, &tio;;
fc3346
     }
fc3346
 }
fc3346
 
fc3346
@@ -120,7 +123,7 @@
fc3346
 watchdog_pwd_decrypt(pwdenc_t *pwdcrypt)
fc3346
 {
fc3346
     if (!pwdcrypt->ptr) {
fc3346
-	return NULL;
fc3346
+    	return NULL;
fc3346
     }
fc3346
     {
fc3346
         char *buf;
fc3346
@@ -331,6 +334,52 @@
fc3346
 }
fc3346
 #endif
fc3346
 
fc3346
+/*
fc3346
+ * is systemd running
fc3346
+ */
fc3346
+bool
fc3346
+check_systemd_running ()
fc3346
+{
fc3346
+  struct stat a, b;
fc3346
+
fc3346
+  /* We simply test whether the systemd cgroup hierarchy is
fc3346
+   * mounted */
fc3346
+
fc3346
+  return (lstat("/sys/fs/cgroup", &a) == 0)
fc3346
+     && (lstat("/sys/fs/cgroup/systemd", &b) == 0)
fc3346
+     && (a.st_dev != b.st_dev);
fc3346
+
fc3346
+}
fc3346
+
fc3346
+static bool
fc3346
+watchdog_get_passwd_systemd(const char *prompt, char *input, const int capacity)
fc3346
+{
fc3346
+    char *cmd, *ret;
fc3346
+    FILE *ask_pass_fp = NULL;
fc3346
+    bool retval = false;
fc3346
+
fc3346
+    /* temporarily disable SIGCHLD handler */
fc3346
+    disable_sigchld_for_one_signal();
fc3346
+
fc3346
+    cmd = ret = NULL;
fc3346
+    if (asprintf(&cmd, "systemd-ask-password \"%s\"", prompt) >= 0) {
fc3346
+        ask_pass_fp = popen (cmd, "re");
fc3346
+        free (cmd);
fc3346
+    }
fc3346
+
fc3346
+    if (ask_pass_fp) {
fc3346
+        ret = fgets(input, capacity, ask_pass_fp);
fc3346
+        pclose(ask_pass_fp);
fc3346
+    }
fc3346
+
fc3346
+    if (ret) {
fc3346
+        int len = strlen(input);
fc3346
+        if (input[len - 1] == '\n') input[len - 1] = '\0';
fc3346
+        return true;
fc3346
+    }
fc3346
+    return false;
fc3346
+}
fc3346
+
fc3346
 int
fc3346
 watchdog_pwd_prompt(const char *prompt, int serial, char **pwdvalue)
fc3346
 {
fc3346
@@ -340,6 +389,25 @@
fc3346
     int isTTY = isatty(infd);
fc3346
     int plen;
fc3346
 
fc3346
+    char *started_by_systemd = getenv("STARTED_BY_SYSTEMD");
fc3346
+
fc3346
+    if (started_by_systemd) {
fc3346
+        if (!check_systemd_running()) {
fc3346
+            fprintf(stderr,
fc3346
+                "STARTED_BY_SYSTEMD set indicating that nuxwdog has been started by systemd, but "
fc3346
+                "systemd is not running.");
fc3346
+            return -1;
fc3346
+        }
fc3346
+
fc3346
+        char pvalue[256];
fc3346
+        pvalue[0] = '\0'; 
fc3346
+        if (watchdog_get_passwd_systemd(prompt, pvalue, 256)) {
fc3346
+            *pwdvalue = strdup(pvalue);
fc3346
+            return 0;
fc3346
+        }
fc3346
+        return -1;
fc3346
+    }
fc3346
+
fc3346
     /* Turn off buffering to avoid leaving password in I/O buffer */
fc3346
     setbuf(stdin, NULL);
fc3346
 
fc3346
@@ -400,4 +468,3 @@
fc3346
 
fc3346
     return 0;
fc3346
 }
fc3346
-
fc3346
Index: src/com/redhat/nuxwdog/wdsignals.cpp
fc3346
===================================================================
fc3346
--- src/com/redhat/nuxwdog/wdsignals.cpp	(revision 87)
fc3346
+++ src/com/redhat/nuxwdog/wdsignals.cpp	(revision 89)
fc3346
@@ -37,6 +37,8 @@
fc3346
 
fc3346
 static int watchdog_pending_signal = 0;
fc3346
 
fc3346
+static struct sigaction prev_sigchld_handler;
fc3346
+
fc3346
 static void
fc3346
 sig_term(int sig)
fc3346
 {
fc3346
@@ -217,3 +219,25 @@
fc3346
         sigsuspend(&holdset);
fc3346
     }
fc3346
 }
fc3346
+
fc3346
+static void
fc3346
+temp_sig_chld(int sig)
fc3346
+{
fc3346
+    sigaction(SIGCHLD, &prev_sigchld_handler, NULL);
fc3346
+}
fc3346
+
fc3346
+void
fc3346
+disable_sigchld_for_one_signal()
fc3346
+{
fc3346
+    struct sigaction sa;
fc3346
+    sa.sa_handler = temp_sig_chld;
fc3346
+    sigemptyset(&sa.sa_mask);
fc3346
+    sigaddset(&sa.sa_mask, SIGCHLD);
fc3346
+#ifdef SA_NOCLDSTOP
fc3346
+    sa.sa_flags = SA_NOCLDSTOP;
fc3346
+#else
fc3346
+    sa.sa_flags = 0;
fc3346
+#endif /* SA_NOCLDSTOP */
fc3346
+    sigaction(SIGCHLD, &sa, &prev_sigchld_handler);
fc3346
+}
fc3346
+