+#ifdef HAVE_LIBSYSTEMD
+// systemd notify support
+
+static bool notify_enabled = false;
+
+static inline void notify_init()
+{
+ if (!getenv("NOTIFY_SOCKET"))
+ return;
+ notify_enabled = true;
+}
+
+static inline bool notify_post_init()
+{
+ if (!notify_enabled)
+ return true;
+ if (do_fork) {
+ PrintOut(LOG_CRIT, "Option -n (--no-fork) is required if 'Type=notify' is set.\n");
+ return false;
+ }
+ return true;
+}
+
+static void notify_msg(const char * msg, bool ready = false)
+{
+ if (!notify_enabled)
+ return;
+ if (debugmode) {
+ pout("sd_notify(0, \"%sSTATUS=%s\")\n", (ready ? "READY=1\\n" : ""), msg);
+ return;
+ }
+ sd_notifyf(0, "%sSTATUS=%s", (ready ? "READY=1\n" : ""), msg);
+}
+
+static void notify_check(int numdev)
+{
+ if (!notify_enabled)
+ return;
+ char msg[32];
+ snprintf(msg, sizeof(msg), "Checking %d device%s ...",
+ numdev, (numdev != 1 ? "s" : ""));
+ notify_msg(msg);
+}
+
+static void notify_wait(time_t wakeuptime, int numdev)
+{
+ if (!notify_enabled)
+ return;
+ char ts[16], msg[64];
+ strftime(ts, sizeof(ts), "%H:%M:%S", localtime(&wakeuptime));
+ snprintf(msg, sizeof(msg), "Next check of %d device%s will start at %s",
+ numdev, (numdev != 1 ? "s" : ""), ts);
+ static bool ready = true; // first call notifies READY=1
+ notify_msg(msg, ready);
+ ready = false;
+}
+
+static void notify_exit(int status)
+{
+ if (!notify_enabled)
+ return;
+ const char * msg;
+ switch (status) {
+ case 0: msg = "Exiting ..."; break;
+ case EXIT_BADCMD: msg = "Error in command line (see SYSLOG)"; break;
+ case EXIT_BADCONF: case EXIT_NOCONF:
+ case EXIT_READCONF: msg = "Error in config file (see SYSLOG)"; break;
+ case EXIT_BADDEV: msg = "Unable to register a device (see SYSLOG)"; break;
+ case EXIT_NODEV: msg = "No devices to monitor"; break;
+ default: msg = "Error (see SYSLOG)"; break;
+ }
+ notify_msg(msg);
+}
+
+#else // HAVE_LIBSYSTEMD
+// No systemd notify support
+
+static inline bool notify_post_init()
+{
+#ifdef __linux__
+ if (getenv("NOTIFY_SOCKET")) {
+ PrintOut(LOG_CRIT, "This version of smartd was build without 'Type=notify' support.\n");
+ return false;
+ }
+#endif
+ return true;
+}
+
+static inline void notify_init() { }
+static inline void notify_msg(const char *) { }
+static inline void notify_check(int) { }
+static inline void notify_wait(time_t, int) { }
+static inline void notify_exit(int) { }
+
+#endif // HAVE_LIBSYSTEMD
+