chiark / gitweb /
build-sys: fix make distcheck
[elogind.git] / initctl.c
index a4356759c2e03fcb1e67c83a9a6599efcb38bb28..9d8eceea52ca25df06bc168c11247fe3f7197746 100644 (file)
--- a/initctl.c
+++ b/initctl.c
@@ -39,8 +39,9 @@
 #include "log.h"
 #include "list.h"
 #include "initreq.h"
+#include "manager.h"
+#include "sd-daemon.h"
 
-#define SERVER_FD_START 3
 #define SERVER_FD_MAX 16
 #define TIMEOUT ((int) (10*MSEC_PER_SEC))
 
@@ -67,42 +68,35 @@ struct Fifo {
 };
 
 static const char *translate_runlevel(int runlevel) {
+        static const struct {
+                const int runlevel;
+                const char *special;
+        } table[] = {
+                { '0', SPECIAL_RUNLEVEL0_TARGET },
+                { '1', SPECIAL_RUNLEVEL1_TARGET },
+                { 's', SPECIAL_RUNLEVEL1_TARGET },
+                { 'S', SPECIAL_RUNLEVEL1_TARGET },
+                { '2', SPECIAL_RUNLEVEL2_TARGET },
+                { '3', SPECIAL_RUNLEVEL3_TARGET },
+                { '4', SPECIAL_RUNLEVEL4_TARGET },
+                { '5', SPECIAL_RUNLEVEL5_TARGET },
+                { '6', SPECIAL_RUNLEVEL6_TARGET },
+        };
 
-        switch (runlevel) {
-
-        case '0':
-                return "halt.target";
-
-        case '1':
-        case 's':
-        case 'S':
-                return "rescue.target";
-
-        case '2':
-                return "runlevel2.target";
-
-        case '3':
-                return "runlevel3.target";
-
-        case '4':
-                return "runlevel4.target";
-
-        case '5':
-                return "runlevel5.target";
+        unsigned i;
 
-        case '6':
-                return "reboot.target";
+        for (i = 0; i < ELEMENTSOF(table); i++)
+                if (table[i].runlevel == runlevel)
+                        return table[i].special;
 
-        default:
-                return NULL;
-        }
+        return NULL;
 }
 
 static void change_runlevel(Server *s, int runlevel) {
         const char *target;
         DBusMessage *m = NULL, *reply = NULL;
         DBusError error;
-        const char *path, *replace = "replace";
+        const char *path, *replace = "isolate";
 
         assert(s);
 
@@ -115,7 +109,7 @@ static void change_runlevel(Server *s, int runlevel) {
 
         log_debug("Running request %s", target);
 
-        if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1", "GetUnit"))) {
+        if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "LoadUnit"))) {
                 log_error("Could not allocate message.");
                 goto finish;
         }
@@ -246,55 +240,12 @@ static void fifo_free(Fifo *f) {
                 if (f->server)
                         epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL);
 
-                assert_se(close_nointr(f->fd) == 0);
+                close_nointr_nofail(f->fd);
         }
 
         free(f);
 }
 
-static int verify_environment(unsigned *n_sockets) {
-        unsigned long long pid;
-        const char *e;
-        int r;
-        unsigned ns;
-
-        assert_se(n_sockets);
-
-        if (!(e = getenv("LISTEN_PID"))) {
-                log_error("Missing $LISTEN_PID environment variable.");
-                return -ENOENT;
-        }
-
-        if ((r = safe_atollu(e, &pid)) < 0) {
-                log_error("Failed to parse $LISTEN_PID: %s", strerror(-r));
-                return r;
-        }
-
-        if (pid != (unsigned long long) getpid()) {
-                log_error("Socket nor for me.");
-                return -ENOENT;
-        }
-
-        if (!(e = getenv("LISTEN_FDS"))) {
-                log_error("Missing $LISTEN_FDS environment variable.");
-                return -ENOENT;
-        }
-
-        if ((r = safe_atou(e, &ns)) < 0) {
-                log_error("Failed to parse $LISTEN_FDS: %s", strerror(-r));
-                return -E2BIG;
-        }
-
-        if (ns <= 0 || ns > SERVER_FD_MAX) {
-                log_error("Wrong number of file descriptors passed: %s", e);
-                return -E2BIG;
-        }
-
-        *n_sockets = ns;
-
-        return 0;
-}
-
 static void server_done(Server *s) {
         assert(s);
 
@@ -302,7 +253,7 @@ static void server_done(Server *s) {
                 fifo_free(s->fifos);
 
         if (s->epoll_fd >= 0)
-                assert_se(close_nointr(s->epoll_fd) == 0);
+                close_nointr_nofail(s->epoll_fd);
 
         if (s->bus)
                 dbus_connection_unref(s->bus);
@@ -341,14 +292,14 @@ static int server_init(Server *s, unsigned n_sockets) {
                 zero(ev);
                 ev.events = EPOLLIN;
                 ev.data.ptr = f;
-                if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, SERVER_FD_START+i, &ev) < 0) {
+                if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, SD_LISTEN_FDS_START+i, &ev) < 0) {
                         r = -errno;
                         fifo_free(f);
                         log_error("Failed to add fifo fd to epoll object: %s", strerror(errno));
                         goto fail;
                 }
 
-                f->fd = SERVER_FD_START+i;
+                f->fd = SD_LISTEN_FDS_START+i;
                 LIST_PREPEND(Fifo, fifo, s->fifos, f);
                 f->server = s;
                 s->n_fifos ++;
@@ -392,15 +343,24 @@ static int process_event(Server *s, struct epoll_event *ev) {
 
 int main(int argc, char *argv[]) {
         Server server;
-        int r = 3;
-        unsigned n;
+        int r = 3, n;
+
+        log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
+        log_parse_environment();
 
         log_info("systemd-initctl running as pid %llu", (unsigned long long) getpid());
 
-        if (verify_environment(&n) < 0)
+        if ((n = sd_listen_fds(true)) < 0) {
+                log_error("Failed to read listening file descriptors from environment: %s", strerror(-r));
                 return 1;
+        }
+
+        if (n <= 0 || n > SERVER_FD_MAX) {
+                log_error("No or too many file descriptors passed.");
+                return 2;
+        }
 
-        if (server_init(&server, n) < 0)
+        if (server_init(&server, (unsigned) n) < 0)
                 return 2;
 
         for (;;) {