wip: Move systemd listener to a separate file
authorŁukasz Stelmach <l.stelmach@samsung.com>
Wed, 19 Apr 2017 13:10:59 +0000 (15:10 +0200)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Wed, 19 Apr 2017 13:10:59 +0000 (15:10 +0200)
Makefile.am
src/faultd.c
src/systemd.c [new file with mode: 0644]
src/systemd.h [new file with mode: 0644]

index f19d8937f639be320668ae5b528a8c6754e126bd..1ceb44d1df2405669374f1c65088b0fed5702cf8 100644 (file)
@@ -27,5 +27,8 @@ SED_PROCESS = \
        $(SED_PROCESS)
 
 sbin_PROGRAMS = faultd
-faultd_SOURCES = src/faultd.c src/audit.c
+faultd_SOURCES = \
+    src/audit.c \
+    src/faultd.c \
+    src/systemd.c
 faultd_LDADD = $(LIBSYSTEMD_LIBS) ${AUDIT_LIBS}
index 5ed966eb0bfc66ca12278fdbc08f70893c868a38..d063b7e18a8ad36bb8abd439f998567332c68bd0 100644 (file)
 #include <systemd/sd-event.h>
 #include <signal.h>
 #include "audit.h"
+#include "systemd.h"
 
 static int terminate = 0;
 
-int on_unit_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *ret_error);
-int dbus_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata);
 int sigint_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata);
 
 int sigint_handler(sd_event_source *s,
@@ -39,130 +38,17 @@ int sigint_handler(sd_event_source *s,
   return 0;
 }
 
-int on_unit_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
-  int rc = 1;
-  /* const char* path; */
-  /* path = NULL; */
-  uint8_t type;
-
-  fprintf(stdout,"'");
-  fflush(stdout);
-  rc = sd_bus_message_get_type(m, &type);
-  if (rc < 0) {
-    fprintf(stderr, "Oops!\n");
-    rc = rc;
-    goto finish;
-  }
-
-  fprintf(stdout, "Received a message!\n");
-  fprintf(stdout, "    Type: %s\n",
-          type ==  SD_BUS_MESSAGE_METHOD_CALL ? "method call" :
-          (type ==  SD_BUS_MESSAGE_METHOD_RETURN ? "method return" :
-           (type ==  SD_BUS_MESSAGE_METHOD_ERROR ? "method error" :
-            (type ==  SD_BUS_MESSAGE_SIGNAL ? "signal" : "INVALID"))));
-  fprintf(stdout, "    Interface: %s\n", sd_bus_message_get_interface(m));
-  fprintf(stdout, "    Member:    %s\n", sd_bus_message_get_member(m));
-  fprintf(stdout, "    Path:      %s\n", sd_bus_message_get_path(m));
-
-finish:
-  return rc;
-}
-
-int dbus_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
-  sd_bus* bus = userdata;
-  sd_bus_message *m = NULL;
-  int rc=1;
-
-  fprintf(stdout,".");
-  fflush(stdout);
-
-  /* for (;;) { */
-
-  rc = sd_bus_process(bus, &m);
-  if (rc < 0) {
-    fprintf(stderr, "Failed to process the bus.\n");
-    return rc;
-  }
-
-  return 1;
-
-  if (m == NULL) {
-    fprintf(stderr, "No message.\n");
-    return 1;
-  } else {
-    uint8_t type;
-    int _rc;
-    _rc = sd_bus_message_get_type(m, &type);
-    if (_rc < 0) {
-      fprintf(stderr, "Oops!\n");
-      rc = rc;
-      goto finish;
-    }
-    if (type != SD_BUS_MESSAGE_SIGNAL ||
-       strcmp("org.freedesktop.DBus.Properties", sd_bus_message_get_interface(m)) != 0 ||
-       strcmp("PropertiesChanged", sd_bus_message_get_member(m)) != 0 ||
-       strncmp("/org/freedesktop/systemd1/unit/", sd_bus_message_get_path(m), 31) != 0) {
-      goto finish;
-    }
-    fprintf(stdout, "Received a message!\n");
-    fprintf(stdout, "    Type: %s\n",
-           type ==  SD_BUS_MESSAGE_METHOD_CALL ? "method call" :
-           (type ==  SD_BUS_MESSAGE_METHOD_RETURN ? "method return" :
-            (type ==  SD_BUS_MESSAGE_METHOD_ERROR ? "method error" :
-             (type ==  SD_BUS_MESSAGE_SIGNAL ? "signal" : "INVALID"))));
-    fprintf(stdout, "    Interface: %s\n", sd_bus_message_get_interface(m));
-    fprintf(stdout, "    Member:    %s\n", sd_bus_message_get_member(m));
-    fprintf(stdout, "    Path:      %s\n", sd_bus_message_get_path(m));
-  }
-
-  /* if (rc > 0) */
-  /*   continue; */
-  /* } */
-
-finish:
-  sd_bus_message_unref(m);
-  return rc;
-}
-
 int main(int ac, char* av[])
 {
-  sd_event* loop;
-  /* sd_event_source* source; */
-  sd_bus_error error = SD_BUS_ERROR_NULL;
-  sd_bus *bus = NULL;
-  /* const char *path; */
-  int rc;
   int aufd;
+  int rc;
+  sd_bus *bus = NULL;
+  sd_event* loop;
   sigset_t ss;
 
   rc = sd_bus_default_system(&bus);
   if (rc < 0) {
     fprintf(stderr, "Failed to acquire the defult system bus connection.\n");
-    return 1;
-  }
-
-  rc = sd_bus_add_match(bus,
-                        NULL,
-                        "type='signal',sender='org.freedesktop.systemd1',"
-                        "interface='org.freedesktop.DBus.Properties',"
-                        "member='PropertiesChanged',"
-                        "path_namespace='/org/freedesktop/systemd1/unit'",
-                        on_unit_properties_changed,
-                        NULL);
-  if (rc < 0) {
-    fprintf(stderr, "Failed to add match");
-    return -1;
-  }
-
-  rc = sd_bus_call_method(bus,
-                         "org.freedesktop.systemd1",
-                         "/org/freedesktop/systemd1",
-                         "org.freedesktop.systemd1.Manager",
-                         "Subscribe",
-                         &error,
-                         NULL, NULL);
-  if (rc < 0) {
-    fprintf(stderr, "Failed to subscribe.\n");
     return -1;
   }
 
@@ -173,43 +59,22 @@ int main(int ac, char* av[])
   }
 
   /* If there is way to register a catch-all handler */
-  sd_bus_attach_event(bus, loop, SD_EVENT_PRIORITY_NORMAL);
+  /* sd_bus_attach_event(bus, loop, SD_EVENT_PRIORITY_NORMAL); */
   sigemptyset(&ss);
   sigaddset(&ss, SIGINT);
   rc = sigprocmask(SIG_BLOCK, &ss, NULL);
   rc = sd_event_add_signal(loop, NULL, SIGINT, sigint_handler, loop);
 
 
-//  sd_event_add_io(loop, NULL,   sd_bus_get_fd(bus), EPOLLIN | EPOLLOUT, dbus_handler, (void*)bus);
   aufd = faultd_audit_init(loop);
-
+  faultd_systemd_init(loop);
   printf("Hello world!\n");
 
-#if 0
-  for (;;) {
-    rc = sd_event_get_state(loop);
-    if (rc < 0)
-      return rc;
-    if (rc == SD_EVENT_FINISHED)
-      return 0;
+  sd_event_loop(loop);
 
-    rc = sd_event_run(loop, (uint64_t) -1);
-    if (rc < 0) {
-      fprintf(stderr, "Failed to wait on the bus.\n");
-      break;
-    }
-    fprintf(stdout, ",");
-    fflush(stdout);
+  faultd_audit_close(aufd);
+  faultd_systemd_close();
 
-    if (terminate) {
-           printf("Closing...\n");
-           break;
-    }
-  }
-#else
-  sd_event_loop(loop);
-#endif
   sd_bus_close(bus);
-  faultd_audit_close(aufd);
   return 0;
 }
diff --git a/src/systemd.c b/src/systemd.c
new file mode 100644 (file)
index 0000000..ef624ef
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * This file is part of faultd.
+ *
+ * Copyright © 2017 Samsung Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <poll.h>
+#include <systemd/sd-bus.h>
+#include <systemd/sd-event.h>
+#include "systemd.h"
+
+static int on_unit_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *ret_error);
+
+int  faultd_systemd_init(sd_event* loop) {
+  sd_bus_error error = SD_BUS_ERROR_NULL;
+  sd_bus *bus = NULL;
+  int rc;
+
+  rc = sd_bus_default_system(&bus);
+  if (rc < 0) {
+    fprintf(stderr, "Failed to acquire the defult system bus connection.\n");
+    return -1;
+  }
+
+  rc = sd_bus_attach_event(bus, loop, SD_EVENT_PRIORITY_NORMAL);
+  if (rc < 0) {
+    fprintf(stderr, "Failed to attach the bus to the event loop.\n");
+    return -1;
+  }
+
+  rc = sd_bus_add_match(bus,
+                        NULL,
+                        "type='signal',sender='org.freedesktop.systemd1',"
+                        "interface='org.freedesktop.DBus.Properties',"
+                        "member='PropertiesChanged',"
+                        "path_namespace='/org/freedesktop/systemd1/unit'",
+                        on_unit_properties_changed,
+                        NULL);
+  if (rc < 0) {
+    fprintf(stderr, "Failed to add match");
+    return -1;
+  }
+
+  rc = sd_bus_call_method(bus,
+                         "org.freedesktop.systemd1",
+                         "/org/freedesktop/systemd1",
+                         "org.freedesktop.systemd1.Manager",
+                         "Subscribe",
+                         &error,
+                         NULL, NULL);
+  if (rc < 0) {
+    fprintf(stderr, "Failed to subscribe.\n");
+    return -1;
+  }
+
+  return 0;
+}
+
+int faultd_systemd_close() {
+  sd_bus_error error = SD_BUS_ERROR_NULL;
+  sd_bus *bus = NULL;
+  int rc;
+
+  rc = sd_bus_default_system(&bus);
+  if (rc < 0) {
+    fprintf(stderr, "Failed to acquire the defult system bus connection.\n");
+    return -1;
+  }
+
+  rc = sd_bus_call_method(bus,
+                         "org.freedesktop.systemd1",
+                         "/org/freedesktop/systemd1",
+                         "org.freedesktop.systemd1.Manager",
+                         "Unsubscribe",
+                         &error,
+                         NULL, NULL);
+  if (rc < 0) {
+    fprintf(stderr, "Failed to unsubscribe.\n");
+    return -1;
+  }
+  return 0;
+}
+
+static int on_unit_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+  int rc = 1;
+  const char *interface;
+  /* const char* path; */
+  /* path = NULL; */
+  uint8_t type;
+
+  rc = sd_bus_message_read(m, "s", &interface);
+  if (rc < 0) {
+    fprintf(stderr, "Invalid message format.\n");
+    goto finish;
+  }
+  if (strcmp("org.freedesktop.systemd1.Unit", interface) != 0) {
+    rc = 0;
+    goto finish;
+  }
+
+  fprintf(stdout,"'");
+  fflush(stdout);
+  rc = sd_bus_message_get_type(m, &type);
+  if (rc < 0) {
+    fprintf(stderr, "Oops!\n");
+    goto finish;
+  }
+
+  fprintf(stdout, "Received a message!\n");
+  fprintf(stdout, "    Type: %s\n",
+          type ==  SD_BUS_MESSAGE_METHOD_CALL ? "method call" :
+          (type ==  SD_BUS_MESSAGE_METHOD_RETURN ? "method return" :
+           (type ==  SD_BUS_MESSAGE_METHOD_ERROR ? "method error" :
+            (type ==  SD_BUS_MESSAGE_SIGNAL ? "signal" : "INVALID"))));
+  fprintf(stdout, "    Interface:  %s\n", sd_bus_message_get_interface(m));
+  fprintf(stdout, "    Member:     %s\n", sd_bus_message_get_member(m));
+  fprintf(stdout, "    Path:       %s\n", sd_bus_message_get_path(m));
+  fprintf(stdout, "    Message If: %s\n", interface);
+
+  rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
+  if (rc < 0) {
+    rc = 0;
+  }
+  fprintf(stdout, "    Message dictionary:\n");
+  while((rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
+    const char *key;
+
+    rc = sd_bus_message_read(m, "s", &key);
+    if (rc < 0) {
+      fprintf(stderr, "Failed to read a DICT_ENTRY: %s.\n", strerror(-rc));
+      rc = 0;
+      goto finish;
+    }
+
+    fprintf(stdout, "        %s", key);
+    if (strcmp("ActiveState", key) == 0) {
+      const char *value;
+
+      rc = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "s");
+      if (rc < 0) {
+        /* XXX */
+        rc = 0;
+        goto finish;
+      }
+      rc = sd_bus_message_read(m, "s", &value);
+      if (rc < 0) {
+        log_error_errno(rc, "Failed to read the AciveSate value: %m.\n");
+        rc = 0;
+        goto finish;
+      }
+      rc = sd_bus_message_exit_container(m);
+      fprintf(stdout, ":%s", value);
+
+    } else {
+
+      rc = sd_bus_message_skip(m, "v");
+      if (rc < 0) {
+        fprintf(stderr, "Failed to skip a value.");
+        rc = 0;
+        goto finish;
+      }
+    }
+    fprintf(stdout,"\n");
+
+    rc = sd_bus_message_exit_container(m);
+    if (rc < 0) {
+      fprintf(stderr, "Failed to exit a container: %s.\n", strerror(-rc));
+      rc = 0;
+      goto finish;
+    }
+  }
+
+  rc = sd_bus_message_exit_container(m);
+  if (rc < 0) {
+    rc = 0;
+  }
+finish:
+  return rc;
+}
diff --git a/src/systemd.h b/src/systemd.h
new file mode 100644 (file)
index 0000000..64ec722
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef FAULTD_SYSTEMD_H
+#define FAULTD_SYSTEMD_H
+
+/** Initialize communication with DBus and subscribe for systemd signals
+ * @return status */
+int faultd_systemd_init(sd_event *loop);
+
+/** Unsubscribe from systemd signals
+ * @reurn  status */
+int faultd_systemd_close(void);
+
+#endif /* FAULT_SYSTEMD_H */