summaryrefslogtreecommitdiff
path: root/systemd.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-06-23 16:25:36 +0200
committerDavid Härdeman <david@hardeman.nu>2020-06-23 16:25:36 +0200
commit8c27290245b7bcc7cd2f72f3b4a7562294b43bbe (patch)
tree54bae7909a94bfc598df7b88d9794742daf0bb31 /systemd.c
parent973ae757342b91e3e6aafd07e0c0a24af84aad98 (diff)
Split directories better
Diffstat (limited to 'systemd.c')
-rw-r--r--systemd.c219
1 files changed, 0 insertions, 219 deletions
diff --git a/systemd.c b/systemd.c
deleted file mode 100644
index a44b0d8..0000000
--- a/systemd.c
+++ /dev/null
@@ -1,219 +0,0 @@
-#include <string.h>
-#include <stdlib.h>
-#include <systemd/sd-bus.h>
-
-#include "main.h"
-#include "server.h"
-#include "systemd.h"
-
-#define SYSTEMD_DBUS_SERVICE "org.freedesktop.systemd1"
-#define SYSTEMD_DBUS_INTERFACE "org.freedesktop.systemd1.Unit"
-#define SYSTEMD_DBUS_PATH_PREFIX "/org/freedesktop/systemd1/unit/"
-
-static inline char
-tohex(uint8_t val)
-{
- static const char hex[] = "0123456789abcdef";
-
- return hex[val & 0x0f];
-}
-
-/*
- * Creates an escaped D-Bus object path for a given systemd service
- *
- * Escaping rules are documented here:
- * https://dbus.freedesktop.org/doc/dbus-specification.html
- *
- * Essentially, everyting but a-z, A-Z, 0-9 is replaced by _xx where xx is
- * the hexadecimal value of the character.
- *
- * Example: minecraft@world1.service -> minecraft_40world1_2eservice
- */
-char *
-systemd_object_path(const char *service)
-{
- char *r;
- char *d;
- const char *s;
-
- assert_return(service && !empty_str(service), NULL);
-
- r = zmalloc(strlen(SYSTEMD_DBUS_PATH_PREFIX) + strlen(service) * 3 + 1);
- if (!r)
- return NULL;
-
- memcpy(r, SYSTEMD_DBUS_PATH_PREFIX, strlen(SYSTEMD_DBUS_PATH_PREFIX));
- d = r + strlen(SYSTEMD_DBUS_PATH_PREFIX);
-
- for (s = service; *s; s++) {
- if ((*s >= 'a' && *s <= 'z') ||
- (*s >= 'A' && *s <= 'Z') ||
- (*s >= '0' && *s <= '9')) {
- *(d++) = *s;
- continue;
- }
-
- *(d++) = '_';
- *(d++) = tohex(*s >> 4);
- *(d++) = tohex(*s);
- }
-
- *d = '\0';
- return r;
-}
-
-void
-systemd_delete()
-{
- assert_return_silent(cfg->sd_bus);
-
- sd_bus_unref(cfg->sd_bus);
- cfg->sd_bus = NULL;
-}
-
-static sd_bus *
-get_bus()
-{
- int r;
-
- if (cfg->sd_bus_failed)
- return NULL;
-
- if (!cfg->sd_bus) {
- r = sd_bus_open_user(&cfg->sd_bus);
- if (r < 0) {
- error("failed to connect to user system bus: %s", strerror(-r));
- cfg->sd_bus_failed = true;
- return NULL;
- }
- }
-
- return cfg->sd_bus;
-}
-
-/*
- * Check if a systemd service is running.
- *
- * This is equivalent to (assuming service minecraft@world1):
- * gdbus call --session
- * --dest org.freedesktop.systemd1
- * --object-path /org/freedesktop/systemd1/unit/minecraft_40world1_2eservice
- * --method org.freedesktop.DBus.Properties.Get
- * "org.freedesktop.systemd1.Unit"
- * "ActiveState"
- */
-bool
-systemd_service_running(struct server *server)
-{
- sd_bus *bus = get_bus();
- sd_bus_error error = SD_BUS_ERROR_NULL;
- char *status = NULL;
- bool running = false;
- int r;
-
- assert_return(server && bus && server->systemd_service && server->systemd_obj, false);
-
- r = sd_bus_get_property_string(bus,
- SYSTEMD_DBUS_SERVICE,
- server->systemd_obj,
- SYSTEMD_DBUS_INTERFACE,
- "ActiveState",
- &error,
- &status);
- if (r < 0) {
- error("failed to get status for service %s (%s): %s",
- server->systemd_service, server->systemd_obj, error.message);
- goto out;
- }
-
- if (streq(status, "active")) {
- running = true;
- debug(DBG_SYSD, "systemd service %s (%s) is active",
- server->systemd_service, server->systemd_obj);
- } else
- debug(DBG_SYSD, "systemd service %s (%s) is not active",
- server->systemd_service, server->systemd_obj);
-
-out:
- free(status);
- sd_bus_error_free(&error);
- return running;
-}
-
-static bool
-systemd_service_action(struct server *server, const char *action)
-{
- sd_bus_error error = SD_BUS_ERROR_NULL;
- sd_bus_message *m = NULL;
- sd_bus *bus = get_bus();
- const char *path;
- bool performed = false;
- int r;
-
- assert_return(server && bus && server->systemd_service && server->systemd_obj && action, false);
-
- r = sd_bus_call_method(bus,
- SYSTEMD_DBUS_SERVICE,
- server->systemd_obj,
- SYSTEMD_DBUS_INTERFACE,
- action,
- &error,
- &m,
- "s",
- "fail");
- if (r < 0) {
- error("failed to perform action %s on systemd service %s: %s",
- action, server->systemd_service, error.message);
- goto out;
- }
-
- r = sd_bus_message_read(m, "o", &path);
- if (r < 0) {
- error("failed to parse response message: %s", strerror(-r));
- goto out;
- }
-
- verbose("action %s queued for service %s",
- action, server->systemd_service);
- performed = true;
-
-out:
- sd_bus_error_free(&error);
- sd_bus_message_unref(m);
- return performed;
-}
-
-/*
- * Stop systemd service.
- *
- * This is equivalent to (assuming service minecraft@world1):
- * gdbus call --session
- * --dest org.freedesktop.systemd1
- * --object-path /org/freedesktop/systemd1/unit/minecraft_40world1_2eservice
- * --method org.freedesktop.systemd1.Unit.Stop "fail"
- */
-bool
-systemd_service_stop(struct server *server)
-{
- assert_return(server, false);
-
- return systemd_service_action(server, "Stop");
-}
-
-/*
- * Start systemd service.
- *
- * This is equivalent to (assuming service minecraft@world1):
- * gdbus call --session
- * --dest org.freedesktop.systemd1
- * --object-path /org/freedesktop/systemd1/unit/minecraft_40world1_2eservice
- * --method org.freedesktop.systemd1.Unit.Start "fail"
- */
-bool
-systemd_service_start(struct server *server)
-{
- assert_return(server, false);
-
- return systemd_service_action(server, "Start");
-}
-