$(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}
#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,
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;
}
}
/* 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;
}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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 */