]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/systemctl/systemctl.c
tree-wide: beautify remaining copyright statements
[thirdparty/systemd.git] / src / systemctl / systemctl.c
index cae4ff023a07f05ccbbf19f612c12493cdf0bc7e..90ea9db48570df0bca1d646cf1f0329571c80866 100644 (file)
@@ -1,22 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 /***
-  This file is part of systemd.
-
-  Copyright 2010 Lennart Poettering
-  Copyright 2013 Marc-Antoine Perennou
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+  Copyright © 2013 Marc-Antoine Perennou
 ***/
 
 #include <errno.h>
@@ -161,7 +145,7 @@ static enum action {
         ACTION_SUSPEND,
         ACTION_HIBERNATE,
         ACTION_HYBRID_SLEEP,
-        ACTION_SUSPEND_TO_HIBERNATE,
+        ACTION_SUSPEND_THEN_HIBERNATE,
         ACTION_RUNLEVEL2,
         ACTION_RUNLEVEL3,
         ACTION_RUNLEVEL4,
@@ -224,12 +208,6 @@ static int acquire_bus(BusFocus focus, sd_bus **ret) {
 
                 user = arg_scope != UNIT_FILE_SYSTEM;
 
-                if (!user && sd_booted() <= 0) {
-                        /* Print a friendly message when the local system is actually not running systemd as PID 1. */
-                        log_error("System has not been booted with systemd as init system (PID 1). Can't operate.");
-                        return -EHOSTDOWN;
-                }
-
                 if (focus == BUS_MANAGER)
                         r = bus_connect_transport_systemd(arg_transport, arg_host, user, &busses[focus]);
                 else
@@ -252,7 +230,6 @@ static void release_busses(void) {
 }
 
 static void ask_password_agent_open_if_enabled(void) {
-
         /* Open the password agent as a child process if necessary */
 
         if (arg_dry_run)
@@ -316,7 +293,6 @@ static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error)
 }
 
 static bool install_client_side(void) {
-
         /* Decides when to execute enable/disable/... operations
          * client-side rather than server-side. */
 
@@ -437,7 +413,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
 
                 if (!arg_no_legend &&
                     (streq(u->active_state, "failed") ||
-                     STR_IN_SET(u->load_state, "error", "not-found", "masked")))
+                     STR_IN_SET(u->load_state, "error", "not-found", "bad-setting", "masked")))
                         circle_len = 2;
         }
 
@@ -514,7 +490,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
                         underline = true;
                 }
 
-                if (STR_IN_SET(u->load_state, "error", "not-found", "masked") && !arg_plain) {
+                if (STR_IN_SET(u->load_state, "error", "not-found", "bad-setting", "masked") && !arg_plain) {
                         on_circle = ansi_highlight_yellow();
                         off_circle = ansi_normal();
                         circle = true;
@@ -680,8 +656,7 @@ static int get_unit_list(
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        *_reply = reply;
-        reply = NULL;
+        *_reply = TAKE_PTR(reply);
 
         return c;
 }
@@ -752,16 +727,13 @@ static int get_unit_list_recursive(
                         }
                 }
 
-                *_machines = machines;
-                machines = NULL;
+                *_machines = TAKE_PTR(machines);
         } else
                 *_machines = NULL;
 
-        *_unit_infos = unit_infos;
-        unit_infos = NULL;
+        *_unit_infos = TAKE_PTR(unit_infos);
 
-        *_replies = replies;
-        replies = NULL;
+        *_replies = TAKE_PTR(replies);
 
         return c;
 }
@@ -1334,10 +1306,8 @@ static int list_timers(int argc, char *argv[], void *userdata) {
                         .id = u->id,
                         .next_elapse = m,
                         .last_trigger = last,
-                        .triggered = triggered,
+                        .triggered = TAKE_PTR(triggered),
                 };
-
-                triggered = NULL; /* avoid cleanup */
         }
 
         qsort_safe(timer_infos, c, sizeof(struct timer_info),
@@ -1637,7 +1607,6 @@ static int list_dependencies_print(const char *name, int level, unsigned int bra
 }
 
 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
-
         struct DependencyStatusInfo {
                 char **dep[5];
         } info = {};
@@ -1686,6 +1655,7 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha
                                    "org.freedesktop.systemd1",
                                    path,
                                    map[arg_dependency],
+                                   BUS_MAP_STRDUP,
                                    &error,
                                    NULL,
                                    &info);
@@ -1704,8 +1674,7 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha
                 info.dep[i] = strv_free(info.dep[i]);
         }
 
-        *deps = ret;
-        ret = NULL;
+        *deps = TAKE_PTR(ret);
 
         return 0;
 }
@@ -1810,7 +1779,7 @@ static int list_dependencies(int argc, char *argv[], void *userdata) {
         int r;
 
         if (argv[1]) {
-                r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &unit);
+                r = unit_name_mangle(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, &unit);
                 if (r < 0)
                         return log_error_errno(r, "Failed to mangle unit name: %m");
 
@@ -1892,7 +1861,15 @@ static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
                 bus = container;
         }
 
-        r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, NULL, NULL, mi);
+        r = bus_map_all_properties(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        machine_info_property_map,
+                        BUS_MAP_STRDUP,
+                        NULL,
+                        NULL,
+                        mi);
         if (r < 0)
                 return r;
 
@@ -1924,8 +1901,7 @@ static int get_machine_list(
                         return log_oom();
 
                 machine_infos[c].is_host = true;
-                machine_infos[c].name = hn;
-                hn = NULL;
+                machine_infos[c].name = TAKE_PTR(hn);
 
                 (void) get_machine_properties(bus, &machine_infos[c]);
                 c++;
@@ -2110,13 +2086,13 @@ static int get_default(int argc, char *argv[], void *userdata) {
 static int set_default(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *unit = NULL;
         UnitFileChange *changes = NULL;
-        unsigned n_changes = 0;
+        size_t n_changes = 0;
         int r;
 
         assert(argc >= 2);
         assert(argv);
 
-        r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &unit);
+        r = unit_name_mangle_with_suffix(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".target", &unit);
         if (r < 0)
                 return log_error_errno(r, "Failed to mangle unit name: %m");
 
@@ -2462,10 +2438,9 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un
                 if (r < 0)
                         return log_error_errno(r, "Failed to access path '%s': %m", path);
 
-                if (unit_path) {
-                        *unit_path = lpath;
-                        lpath = NULL;
-                }
+                if (unit_path)
+                        *unit_path = TAKE_PTR(lpath);
+
                 return 1;
         }
 
@@ -2497,10 +2472,9 @@ static int unit_find_template_path(
         if (r < 0)
                 return r;
 
-        if (template) {
-                *template = _template;
-                _template = NULL;
-        }
+        if (template)
+                *template = TAKE_PTR(_template);
+
         return r;
 }
 
@@ -2600,14 +2574,12 @@ static int unit_find_paths(
         r = 0;
 
         if (!isempty(path)) {
-                *fragment_path = path;
-                path = NULL;
+                *fragment_path = TAKE_PTR(path);
                 r = 1;
         }
 
         if (dropin_paths && !strv_isempty(dropins)) {
-                *dropin_paths = dropins;
-                dropins = NULL;
+                *dropin_paths = TAKE_PTR(dropins);
                 r = 1;
         }
  not_found:
@@ -2651,40 +2623,38 @@ static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *ac
         return 0;
 }
 
-static int check_triggering_units(
-                sd_bus *bus,
-                const char *name) {
+static int unit_is_masked(sd_bus *bus, const char *name) {
+        _cleanup_free_ char *load_state = NULL;
+        int r;
+
+        r = unit_load_state(bus, name, &load_state);
+        if (r < 0)
+                return r;
 
+        return streq(load_state, "masked");
+}
+
+static int check_triggering_units(sd_bus *bus, const char *name) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_free_ char *path = NULL, *n = NULL, *load_state = NULL;
+        _cleanup_free_ char *n = NULL, *path = NULL;
         _cleanup_strv_free_ char **triggered_by = NULL;
         bool print_warning_label = true;
         UnitActiveState active_state;
         char **i;
         int r;
 
-        r = unit_name_mangle(name, UNIT_NAME_NOGLOB, &n);
+        r = unit_name_mangle(name, 0, &n);
         if (r < 0)
                 return log_error_errno(r, "Failed to mangle unit name: %m");
 
+        r = unit_is_masked(bus, n);
+        if (r != 0)
+                return r < 0 ? r : 0;
+
         path = unit_dbus_path_from_name(n);
         if (!path)
                 return log_oom();
 
-        r = sd_bus_get_property_string(
-                        bus,
-                        "org.freedesktop.systemd1",
-                        path,
-                        "org.freedesktop.systemd1.Unit",
-                        "LoadState",
-                        &error,
-                        &load_state);
-        if (r < 0)
-                return log_error_errno(r, "Failed to get load state of %s: %s", n, bus_error_message(&error, r));
-
-        if (streq(load_state, "masked"))
-                return 0;
-
         r = sd_bus_get_property_strv(
                         bus,
                         "org.freedesktop.systemd1",
@@ -2949,11 +2919,12 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r
 
         STRV_FOREACH(name, names) {
                 char *t;
+                UnitNameMangle options = UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN);
 
                 if (suffix)
-                        r = unit_name_mangle_with_suffix(*name, UNIT_NAME_GLOB, suffix, &t);
+                        r = unit_name_mangle_with_suffix(*name, options, suffix, &t);
                 else
-                        r = unit_name_mangle(*name, UNIT_NAME_GLOB, &t);
+                        r = unit_name_mangle(*name, options, &t);
                 if (r < 0)
                         return log_error_errno(r, "Failed to mangle name: %m");
 
@@ -2991,8 +2962,7 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r
                 }
         }
 
-        *ret = mangled;
-        mangled = NULL; /* do not free */
+        *ret = TAKE_PTR(mangled);
 
         return 0;
 }
@@ -3002,22 +2972,22 @@ static const struct {
         const char *verb;
         const char *mode;
 } action_table[_ACTION_MAX] = {
-        [ACTION_HALT]                 = { SPECIAL_HALT_TARGET,                 "halt",                 "replace-irreversibly" },
-        [ACTION_POWEROFF]             = { SPECIAL_POWEROFF_TARGET,             "poweroff",             "replace-irreversibly" },
-        [ACTION_REBOOT]               = { SPECIAL_REBOOT_TARGET,               "reboot",               "replace-irreversibly" },
-        [ACTION_KEXEC]                = { SPECIAL_KEXEC_TARGET,                "kexec",                "replace-irreversibly" },
-        [ACTION_RUNLEVEL2]            = { SPECIAL_MULTI_USER_TARGET,           NULL,                   "isolate" },
-        [ACTION_RUNLEVEL3]            = { SPECIAL_MULTI_USER_TARGET,           NULL,                   "isolate" },
-        [ACTION_RUNLEVEL4]            = { SPECIAL_MULTI_USER_TARGET,           NULL,                   "isolate" },
-        [ACTION_RUNLEVEL5]            = { SPECIAL_GRAPHICAL_TARGET,            NULL,                   "isolate" },
-        [ACTION_RESCUE]               = { SPECIAL_RESCUE_TARGET,               "rescue",               "isolate" },
-        [ACTION_EMERGENCY]            = { SPECIAL_EMERGENCY_TARGET,            "emergency",            "isolate" },
-        [ACTION_DEFAULT]              = { SPECIAL_DEFAULT_TARGET,              "default",              "isolate" },
-        [ACTION_EXIT]                 = { SPECIAL_EXIT_TARGET,                 "exit",                 "replace-irreversibly" },
-        [ACTION_SUSPEND]              = { SPECIAL_SUSPEND_TARGET,              "suspend",              "replace-irreversibly" },
-        [ACTION_HIBERNATE]            = { SPECIAL_HIBERNATE_TARGET,            "hibernate",            "replace-irreversibly" },
-        [ACTION_HYBRID_SLEEP]         = { SPECIAL_HYBRID_SLEEP_TARGET,         "hybrid-sleep",         "replace-irreversibly" },
-        [ACTION_SUSPEND_TO_HIBERNATE] = { SPECIAL_SUSPEND_TO_HIBERNATE_TARGET, "suspend-to-hibernate", "replace-irreversibly" },
+        [ACTION_HALT]                 = { SPECIAL_HALT_TARGET,                     "halt",                   "replace-irreversibly" },
+        [ACTION_POWEROFF]             = { SPECIAL_POWEROFF_TARGET,                 "poweroff",               "replace-irreversibly" },
+        [ACTION_REBOOT]               = { SPECIAL_REBOOT_TARGET,                   "reboot",                 "replace-irreversibly" },
+        [ACTION_KEXEC]                = { SPECIAL_KEXEC_TARGET,                    "kexec",                  "replace-irreversibly" },
+        [ACTION_RUNLEVEL2]            = { SPECIAL_MULTI_USER_TARGET,               NULL,                     "isolate" },
+        [ACTION_RUNLEVEL3]            = { SPECIAL_MULTI_USER_TARGET,               NULL,                     "isolate" },
+        [ACTION_RUNLEVEL4]            = { SPECIAL_MULTI_USER_TARGET,               NULL,                     "isolate" },
+        [ACTION_RUNLEVEL5]            = { SPECIAL_GRAPHICAL_TARGET,                NULL,                     "isolate" },
+        [ACTION_RESCUE]               = { SPECIAL_RESCUE_TARGET,                   "rescue",                 "isolate" },
+        [ACTION_EMERGENCY]            = { SPECIAL_EMERGENCY_TARGET,                "emergency",              "isolate" },
+        [ACTION_DEFAULT]              = { SPECIAL_DEFAULT_TARGET,                  "default",                "isolate" },
+        [ACTION_EXIT]                 = { SPECIAL_EXIT_TARGET,                     "exit",                   "replace-irreversibly" },
+        [ACTION_SUSPEND]              = { SPECIAL_SUSPEND_TARGET,                  "suspend",                "replace-irreversibly" },
+        [ACTION_HIBERNATE]            = { SPECIAL_HIBERNATE_TARGET,                "hibernate",              "replace-irreversibly" },
+        [ACTION_HYBRID_SLEEP]         = { SPECIAL_HYBRID_SLEEP_TARGET,             "hybrid-sleep",           "replace-irreversibly" },
+        [ACTION_SUSPEND_THEN_HIBERNATE] = { SPECIAL_SUSPEND_THEN_HIBERNATE_TARGET, "suspend-then-hibernate", "replace-irreversibly" },
 };
 
 static enum action verb_to_action(const char *verb) {
@@ -3252,8 +3222,8 @@ static int logind_reboot(enum action a) {
                 description = "put system into hybrid sleep";
                 break;
 
-        case ACTION_SUSPEND_TO_HIBERNATE:
-                method = "SuspendToHibernate";
+        case ACTION_SUSPEND_THEN_HIBERNATE:
+                method = "SuspendThenHibernate";
                 description = "put system into suspend followed by hibernate";
                 break;
 
@@ -3626,7 +3596,7 @@ static int start_special(int argc, char *argv[], void *userdata) {
                            ACTION_SUSPEND,
                            ACTION_HIBERNATE,
                            ACTION_HYBRID_SLEEP,
-                           ACTION_SUSPEND_TO_HIBERNATE)) {
+                           ACTION_SUSPEND_THEN_HIBERNATE)) {
 
                         r = logind_reboot(a);
                         if (r >= 0)
@@ -3917,6 +3887,7 @@ typedef struct UnitStatusInfo {
         /* Socket */
         unsigned n_accepted;
         unsigned n_connections;
+        unsigned n_refused;
         bool accept;
 
         /* Pairs of type, path */
@@ -3972,11 +3943,11 @@ static void print_status_info(
                 UnitStatusInfo *i,
                 bool *ellipsized) {
 
+        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
+        const char *s1, *s2, *active_on, *active_off, *on, *off, *ss;
+        _cleanup_free_ char *formatted_path = NULL;
         ExecStatusInfo *p;
-        const char *active_on, *active_off, *on, *off, *ss;
         usec_t timestamp;
-        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
-        char since2[FORMAT_TIMESTAMP_MAX], *s2;
         const char *path;
         char **t, **t2;
         int r;
@@ -4005,15 +3976,17 @@ static void print_status_info(
         if (i->following)
                 printf("   Follow: unit currently follows state of %s\n", i->following);
 
-        if (streq_ptr(i->load_state, "error")) {
+        if (STRPTR_IN_SET(i->load_state, "error", "not-found", "bad-setting")) {
                 on = ansi_highlight_red();
                 off = ansi_normal();
         } else
                 on = off = "";
 
-        path = i->source_path ? i->source_path : i->fragment_path;
+        path = i->source_path ?: i->fragment_path;
+        if (path && terminal_urlify_path(path, NULL, &formatted_path) >= 0)
+                path = formatted_path;
 
-        if (i->load_error != 0)
+        if (!isempty(i->load_error))
                 printf("   Loaded: %s%s%s (Reason: %s)\n",
                        on, strna(i->load_state), off, i->load_error);
         else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset) &&
@@ -4039,8 +4012,12 @@ static void print_status_info(
                 char ** dropin;
 
                 STRV_FOREACH(dropin, i->dropin_paths) {
-                        if (! dir || last) {
-                                printf(dir ? "        " : "  Drop-In: ");
+                        _cleanup_free_ char *dropin_formatted = NULL;
+                        const char *df;
+
+                        if (!dir || last) {
+                                printf(dir ? "           " :
+                                             "  Drop-In: ");
 
                                 dir = mfree(dir);
 
@@ -4050,13 +4027,19 @@ static void print_status_info(
                                         return;
                                 }
 
-                                printf("%s\n           %s", dir,
+                                printf("%s\n"
+                                       "           %s", dir,
                                        special_glyph(TREE_RIGHT));
                         }
 
                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
 
-                        printf("%s%s", basename(*dropin), last ? "\n" : ", ");
+                        if (terminal_urlify_path(*dropin, basename(*dropin), &dropin_formatted) >= 0)
+                                df = dropin_formatted;
+                        else
+                                df = *dropin;
+
+                        printf("%s%s", df, last ? "\n" : ", ");
                 }
         }
 
@@ -4089,7 +4072,7 @@ static void print_status_info(
         if (endswith(i->id, ".timer")) {
                 char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX],
                      tstamp2[FORMAT_TIMESTAMP_MAX];
-                char *next_rel_time, *next_time;
+                const char *next_rel_time, *next_time;
                 dual_timestamp nw, next = {i->next_elapse_real,
                                            i->next_elapse_monotonic};
                 usec_t next_elapse;
@@ -4098,12 +4081,8 @@ static void print_status_info(
 
                 dual_timestamp_get(&nw);
                 next_elapse = calc_next_elapse(&nw, &next);
-                next_rel_time = format_timestamp_relative(tstamp1,
-                                                          sizeof(tstamp1),
-                                                          next_elapse);
-                next_time = format_timestamp(tstamp2,
-                                             sizeof(tstamp2),
-                                             next_elapse);
+                next_rel_time = format_timestamp_relative(tstamp1, sizeof tstamp1, next_elapse);
+                next_time = format_timestamp(tstamp2, sizeof tstamp2, next_elapse);
 
                 if (next_time && next_rel_time)
                         printf("%s; %s\n", next_time, next_rel_time);
@@ -4159,14 +4138,27 @@ static void print_status_info(
         if (i->what)
                 printf("     What: %s\n", i->what);
 
-        STRV_FOREACH(t, i->documentation)
-                printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
+        STRV_FOREACH(t, i->documentation) {
+                _cleanup_free_ char *formatted = NULL;
+                const char *q;
+
+                if (terminal_urlify(*t, NULL, &formatted) >= 0)
+                        q = formatted;
+                else
+                        q = *t;
+
+                printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", q);
+        }
 
         STRV_FOREACH_PAIR(t, t2, i->listen)
                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
 
-        if (i->accept)
-                printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
+        if (i->accept) {
+                printf(" Accepted: %u; Connected: %u;", i->n_accepted, i->n_connections);
+                if (i->n_refused)
+                        printf(" Refused: %u", i->n_refused);
+                printf("\n");
+        }
 
         LIST_FOREACH(exec, p, i->exec) {
                 _cleanup_free_ char *argv = NULL;
@@ -4355,7 +4347,7 @@ static void print_status_info(
 
                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, extra, k, get_output_flags());
                 } else if (r < 0)
-                        log_warning_errno(r, "Failed to dump process list, ignoring: %s", bus_error_message(&error, r));
+                        log_warning_errno(r, "Failed to dump process list for '%s', ignoring: %s", i->id, bus_error_message(&error, r));
         }
 
         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL)
@@ -4966,6 +4958,7 @@ static int show_one(
                 { "NextElapseUSecMonotonic",        "t",              NULL,           offsetof(UnitStatusInfo, next_elapse_monotonic)             },
                 { "NAccepted",                      "u",              NULL,           offsetof(UnitStatusInfo, n_accepted)                        },
                 { "NConnections",                   "u",              NULL,           offsetof(UnitStatusInfo, n_connections)                     },
+                { "NRefused",                       "u",              NULL,           offsetof(UnitStatusInfo, n_refused)                         },
                 { "Accept",                         "b",              NULL,           offsetof(UnitStatusInfo, accept)                            },
                 { "Listen",                         "a(ss)",          map_listen,     offsetof(UnitStatusInfo, listen)                            },
                 { "SysFSPath",                      "s",              NULL,           offsetof(UnitStatusInfo, sysfs_path)                        },
@@ -5020,6 +5013,7 @@ static int show_one(
                         "org.freedesktop.systemd1",
                         path,
                         show_mode == SYSTEMCTL_SHOW_STATUS ? status_map : property_map,
+                        BUS_MAP_BOOLEAN_AS_BOOL,
                         &error,
                         &reply,
                         &info);
@@ -5153,7 +5147,15 @@ static int show_system_status(sd_bus *bus) {
         if (!hn)
                 return log_oom();
 
-        r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &error, NULL, &mi);
+        r = bus_map_all_properties(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        machine_info_property_map,
+                        BUS_MAP_STRDUP,
+                        &error,
+                        NULL,
+                        &mi);
         if (r < 0)
                 return log_error_errno(r, "Failed to read server status: %s", bus_error_message(&error, r));
 
@@ -5308,25 +5310,8 @@ static int show(int argc, char *argv[], void *userdata) {
         return ret;
 }
 
-static int cat_file(const char *filename, bool newline) {
-        _cleanup_close_ int fd;
-
-        fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
-        if (fd < 0)
-                return -errno;
-
-        printf("%s%s# %s%s\n",
-               newline ? "\n" : "",
-               ansi_highlight_blue(),
-               filename,
-               ansi_normal());
-        fflush(stdout);
-
-        return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
-}
-
 static int cat(int argc, char *argv[], void *userdata) {
-        _cleanup_lookup_paths_free_ LookupPaths lp = {};
+        _cleanup_(lookup_paths_free) LookupPaths lp = {};
         _cleanup_strv_free_ char **names = NULL;
         char **name;
         sd_bus *bus;
@@ -5355,7 +5340,6 @@ static int cat(int argc, char *argv[], void *userdata) {
         STRV_FOREACH(name, names) {
                 _cleanup_free_ char *fragment_path = NULL;
                 _cleanup_strv_free_ char **dropin_paths = NULL;
-                char **path;
 
                 r = unit_find_paths(bus, *name, &lp, &fragment_path, &dropin_paths);
                 if (r < 0)
@@ -5382,17 +5366,9 @@ static int cat(int argc, char *argv[], void *userdata) {
                                 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
                                 ansi_normal());
 
-                if (fragment_path) {
-                        r = cat_file(fragment_path, false);
-                        if (r < 0)
-                                return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
-                }
-
-                STRV_FOREACH(path, dropin_paths) {
-                        r = cat_file(*path, path == dropin_paths);
-                        if (r < 0)
-                                return log_warning_errno(r, "Failed to cat %s: %m", *path);
-                }
+                r = cat_files(fragment_path, dropin_paths, 0);
+                if (r < 0)
+                        return r;
         }
 
         return 0;
@@ -5422,7 +5398,7 @@ static int set_property(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return bus_log_create_error(r);
 
-        r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &n);
+        r = unit_name_mangle(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, &n);
         if (r < 0)
                 return log_error_errno(r, "Failed to mangle unit name: %m");
 
@@ -5684,7 +5660,7 @@ static int switch_root(int argc, char *argv[], void *userdata) {
         if (argc >= 3)
                 init = argv[2];
         else {
-                r = parse_env_file("/proc/cmdline", WHITESPACE,
+                r = parse_env_file(NULL, "/proc/cmdline", WHITESPACE,
                                    "init", &cmdline_init,
                                    NULL);
                 if (r < 0)
@@ -5853,7 +5829,7 @@ static int enable_sysv_units(const char *verb, char **args) {
         int r = 0;
 
 #if HAVE_SYSV_COMPAT
-        _cleanup_lookup_paths_free_ LookupPaths paths = {};
+        _cleanup_(lookup_paths_free) LookupPaths paths = {};
         unsigned f = 0;
 
         /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
@@ -6000,7 +5976,7 @@ static int mangle_names(char **original_names, char ***mangled_names) {
                                 return log_oom();
                         }
                 } else {
-                        r = unit_name_mangle(*name, UNIT_NAME_NOGLOB, i);
+                        r = unit_name_mangle(*name, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, i);
                         if (r < 0) {
                                 *i = NULL;
                                 strv_free(l);
@@ -6092,7 +6068,7 @@ static int unit_exists(LookupPaths *lp, const char *unit) {
         if (r < 0)
                 return r;
 
-        r = bus_map_all_properties(bus, "org.freedesktop.systemd1", path, property_map, &error, &m, &info);
+        r = bus_map_all_properties(bus, "org.freedesktop.systemd1", path, property_map, 0, &error, &m, &info);
         if (r < 0)
                 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
 
@@ -6103,7 +6079,7 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
         _cleanup_strv_free_ char **names = NULL;
         const char *verb = argv[0];
         UnitFileChange *changes = NULL;
-        unsigned n_changes = 0;
+        size_t n_changes = 0;
         int carries_install_info = -1;
         bool ignore_carries_install_info = arg_quiet;
         int r;
@@ -6177,7 +6153,7 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
 
                 if (STR_IN_SET(verb, "mask", "unmask")) {
                         char **name;
-                        _cleanup_lookup_paths_free_ LookupPaths lp = {};
+                        _cleanup_(lookup_paths_free) LookupPaths lp = {};
 
                         r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
                         if (r < 0)
@@ -6299,7 +6275,7 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
 
         if (arg_now && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
                 sd_bus *bus;
-                unsigned len, i;
+                size_t len, i;
 
                 r = acquire_bus(BUS_MANAGER, &bus);
                 if (r < 0)
@@ -6329,14 +6305,14 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *target = NULL;
         const char *verb = argv[0];
         UnitFileChange *changes = NULL;
-        unsigned n_changes = 0;
+        size_t n_changes = 0;
         UnitDependency dep;
         int r = 0;
 
         if (!argv[1])
                 return 0;
 
-        r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &target);
+        r = unit_name_mangle_with_suffix(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".target", &target);
         if (r < 0)
                 return log_error_errno(r, "Failed to mangle unit name: %m");
 
@@ -6410,7 +6386,7 @@ finish:
 
 static int preset_all(int argc, char *argv[], void *userdata) {
         UnitFileChange *changes = NULL;
-        unsigned n_changes = 0;
+        size_t n_changes = 0;
         int r;
 
         if (install_client_side()) {
@@ -6465,7 +6441,7 @@ finish:
 
 static int show_installation_targets_client_side(const char *name) {
         UnitFileChange *changes = NULL;
-        unsigned n_changes = 0, i;
+        size_t n_changes = 0, i;
         UnitFileFlags flags;
         char **p;
         int r;
@@ -6521,7 +6497,6 @@ static int show_installation_targets(sd_bus *bus, const char *name) {
 }
 
 static int unit_is_enabled(int argc, char *argv[], void *userdata) {
-
         _cleanup_strv_free_ char **names = NULL;
         bool enabled;
         char **name;
@@ -6670,8 +6645,7 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
         } else if (r < 0)
                 return log_error_errno(r, "Failed to create temporary file for \"%s\": %m", new_path);
 
-        *ret_tmp_fn = t;
-        t = NULL;
+        *ret_tmp_fn = TAKE_PTR(t);
 
         return 0;
 }
@@ -6702,12 +6676,9 @@ static int get_file_to_edit(
                         return -EEXIST;
                 }
 
-                *ret_path = run;
-                run = NULL;
-        } else {
-                *ret_path = path;
-                path = NULL;
-        }
+                *ret_path = TAKE_PTR(run);
+        } else
+                *ret_path = TAKE_PTR(path);
 
         return 0;
 }
@@ -6801,7 +6772,7 @@ static int run_editor(char **paths) {
                 const char **args;
                 char *editor, **editor_args = NULL;
                 char **tmp_path, **original_path, *p;
-                unsigned n_editor_args = 0, i = 1;
+                size_t n_editor_args = 0, i = 1;
                 size_t argc;
 
                 argc = strv_length(paths)/2 + 1;
@@ -6863,7 +6834,7 @@ static int run_editor(char **paths) {
 }
 
 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
-        _cleanup_lookup_paths_free_ LookupPaths lp = {};
+        _cleanup_(lookup_paths_free) LookupPaths lp = {};
         char **name;
         int r;
 
@@ -6960,6 +6931,17 @@ static int edit(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return log_error_errno(r, "Failed to expand names: %m");
 
+        STRV_FOREACH(tmp, names) {
+                r = unit_is_masked(bus, *tmp);
+                if (r < 0)
+                        return r;
+
+                if (r > 0) {
+                        log_error("Cannot edit %s: unit is masked.", *tmp);
+                        return -EINVAL;
+                }
+        }
+
         r = find_paths_to_edit(bus, names, &paths);
         if (r < 0)
                 return r;
@@ -6972,8 +6954,8 @@ static int edit(int argc, char *argv[], void *userdata) {
                 goto end;
 
         STRV_FOREACH_PAIR(original, tmp, paths) {
-                /* If the temporary file is empty we ignore it.  It's
-                 * useful if the user wants to cancel its modification
+                /* If the temporary file is empty we ignore it.
+                 * This allows the user to cancel the modification.
                  */
                 if (null_or_empty_path(*tmp)) {
                         log_warning("Editing \"%s\" canceled: temporary file is empty.", *original);
@@ -7015,7 +6997,6 @@ end:
 }
 
 static void systemctl_help(void) {
-
         (void) pager_open(arg_no_pager, false);
 
         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
@@ -7152,7 +7133,7 @@ static void systemctl_help(void) {
                "  suspend                             Suspend the system\n"
                "  hibernate                           Hibernate the system\n"
                "  hybrid-sleep                        Hibernate and suspend the system\n"
-               "  suspend-to-hibernate                Suspend the system, wake after a period of\n"
+               "  suspend-then-hibernate              Suspend the system, wake after a period of\n"
                "                                      time and put it into hibernate\n",
                program_invocation_short_name);
 }
@@ -7212,85 +7193,67 @@ static void runlevel_help(void) {
 }
 
 static void help_types(void) {
-        int i;
-
         if (!arg_no_legend)
                 puts("Available unit types:");
-        for (i = 0; i < _UNIT_TYPE_MAX; i++)
-                puts(unit_type_to_string(i));
+
+        DUMP_STRING_TABLE(unit_type, UnitType, _UNIT_TYPE_MAX);
 }
 
 static void help_states(void) {
-        int i;
-
         if (!arg_no_legend)
                 puts("Available unit load states:");
-        for (i = 0; i < _UNIT_LOAD_STATE_MAX; i++)
-                puts(unit_load_state_to_string(i));
+        DUMP_STRING_TABLE(unit_load_state, UnitLoadState, _UNIT_LOAD_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable unit active states:");
-        for (i = 0; i < _UNIT_ACTIVE_STATE_MAX; i++)
-                puts(unit_active_state_to_string(i));
+        DUMP_STRING_TABLE(unit_active_state, UnitActiveState, _UNIT_ACTIVE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable automount unit substates:");
-        for (i = 0; i < _AUTOMOUNT_STATE_MAX; i++)
-                puts(automount_state_to_string(i));
+        DUMP_STRING_TABLE(automount_state, AutomountState, _AUTOMOUNT_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable device unit substates:");
-        for (i = 0; i < _DEVICE_STATE_MAX; i++)
-                puts(device_state_to_string(i));
+        DUMP_STRING_TABLE(device_state, DeviceState, _DEVICE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable mount unit substates:");
-        for (i = 0; i < _MOUNT_STATE_MAX; i++)
-                puts(mount_state_to_string(i));
+        DUMP_STRING_TABLE(mount_state, MountState, _MOUNT_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable path unit substates:");
-        for (i = 0; i < _PATH_STATE_MAX; i++)
-                puts(path_state_to_string(i));
+        DUMP_STRING_TABLE(path_state, PathState, _PATH_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable scope unit substates:");
-        for (i = 0; i < _SCOPE_STATE_MAX; i++)
-                puts(scope_state_to_string(i));
+        DUMP_STRING_TABLE(scope_state, ScopeState, _SCOPE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable service unit substates:");
-        for (i = 0; i < _SERVICE_STATE_MAX; i++)
-                puts(service_state_to_string(i));
+        DUMP_STRING_TABLE(service_state, ServiceState, _SERVICE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable slice unit substates:");
-        for (i = 0; i < _SLICE_STATE_MAX; i++)
-                puts(slice_state_to_string(i));
+        DUMP_STRING_TABLE(slice_state, SliceState, _SLICE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable socket unit substates:");
-        for (i = 0; i < _SOCKET_STATE_MAX; i++)
-                puts(socket_state_to_string(i));
+        DUMP_STRING_TABLE(socket_state, SocketState, _SOCKET_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable swap unit substates:");
-        for (i = 0; i < _SWAP_STATE_MAX; i++)
-                puts(swap_state_to_string(i));
+        DUMP_STRING_TABLE(swap_state, SwapState, _SWAP_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable target unit substates:");
-        for (i = 0; i < _TARGET_STATE_MAX; i++)
-                puts(target_state_to_string(i));
+        DUMP_STRING_TABLE(target_state, TargetState, _TARGET_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable timer unit substates:");
-        for (i = 0; i < _TIMER_STATE_MAX; i++)
-                puts(timer_state_to_string(i));
+        DUMP_STRING_TABLE(timer_state, TimerState, _TIMER_STATE_MAX);
 }
 
 static int systemctl_parse_argv(int argc, char *argv[]) {
-
         enum {
                 ARG_FAIL = 0x100,
                 ARG_REVERSE,
@@ -7582,7 +7545,12 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 's':
-                        arg_signal = signal_from_string_try_harder(optarg);
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(signal, int, _NSIG);
+                                return 0;
+                        }
+
+                        arg_signal = signal_from_string(optarg);
                         if (arg_signal < 0) {
                                 log_error("Failed to parse signal string %s.", optarg);
                                 return -EINVAL;
@@ -7615,6 +7583,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'o':
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX);
+                                return 0;
+                        }
+
                         arg_output = output_mode_from_string(optarg);
                         if (arg_output < 0) {
                                 log_error("Unknown output '%s'.", optarg);
@@ -7672,6 +7645,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_PRESET_MODE:
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(unit_file_preset_mode, UnitFilePresetMode, _UNIT_FILE_PRESET_MAX);
+                                return 0;
+                        }
 
                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
                         if (arg_preset_mode < 0) {
@@ -7707,11 +7684,15 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
+        if (arg_runtime && STRPTR_IN_SET(argv[optind], "disable", "unmask", "preset", "preset-all")) {
+                log_error("--runtime cannot be used with %s", argv[optind]);
+                return -EINVAL;
+        }
+
         return 1;
 }
 
 static int halt_parse_argv(int argc, char *argv[]) {
-
         enum {
                 ARG_HELP = 0x100,
                 ARG_HALT,
@@ -7855,7 +7836,6 @@ static int parse_shutdown_time_spec(const char *t, usec_t *_u) {
 }
 
 static int shutdown_parse_argv(int argc, char *argv[]) {
-
         enum {
                 ARG_HELP = 0x100,
                 ARG_NO_WALL
@@ -7962,7 +7942,6 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
 }
 
 static int telinit_parse_argv(int argc, char *argv[]) {
-
         enum {
                 ARG_HELP = 0x100,
                 ARG_NO_WALL
@@ -8049,7 +8028,6 @@ static int telinit_parse_argv(int argc, char *argv[]) {
 }
 
 static int runlevel_parse_argv(int argc, char *argv[]) {
-
         enum {
                 ARG_HELP = 0x100,
         };
@@ -8151,7 +8129,6 @@ static int parse_argv(int argc, char *argv[]) {
 
 #if HAVE_SYSV_COMPAT
 _pure_ static int action_to_runlevel(void) {
-
         static const char table[_ACTION_MAX] = {
                 [ACTION_HALT] =      '0',
                 [ACTION_POWEROFF] =  '0',
@@ -8180,6 +8157,7 @@ static int talk_initctl(void) {
         _cleanup_close_ int fd = -1;
         char rl;
         int r;
+        const char *p;
 
         rl = action_to_runlevel();
         if (!rl)
@@ -8187,17 +8165,21 @@ static int talk_initctl(void) {
 
         request.runlevel = rl;
 
-        fd = open(INIT_FIFO, O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
+        FOREACH_STRING(p, "/run/initctl", "/dev/initctl") {
+                fd = open(p, O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
+                if (fd >= 0 || errno != ENOENT)
+                        break;
+        }
         if (fd < 0) {
                 if (errno == ENOENT)
                         return 0;
 
-                return log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
+                return log_error_errno(errno, "Failed to open initctl fifo: %m");
         }
 
         r = loop_write(fd, &request, sizeof(request), false);
         if (r < 0)
-                return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
+                return log_error_errno(r, "Failed to write to %s: %m", p);
 
         return 1;
 #else
@@ -8206,7 +8188,6 @@ static int talk_initctl(void) {
 }
 
 static int systemctl_main(int argc, char *argv[]) {
-
         static const Verb verbs[] = {
                 { "list-units",            VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_units },
                 { "list-unit-files",       VERB_ANY, VERB_ANY, 0,                list_unit_files      },
@@ -8250,7 +8231,7 @@ static int systemctl_main(int argc, char *argv[]) {
                 { "suspend",               VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
                 { "hibernate",             VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
                 { "hybrid-sleep",          VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "suspend-to-hibernate",  VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
+                { "suspend-then-hibernate",VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
                 { "default",               VERB_ANY, 1,        VERB_ONLINE_ONLY, start_special        },
                 { "rescue",                VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
                 { "emergency",             VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
@@ -8282,7 +8263,6 @@ static int systemctl_main(int argc, char *argv[]) {
 }
 
 static int reload_with_fallback(void) {
-
         /* First, try systemd via D-Bus. */
         if (daemon_reload(0, NULL, NULL) >= 0)
                 return 0;
@@ -8297,7 +8277,6 @@ static int reload_with_fallback(void) {
 }
 
 static int start_with_fallback(void) {
-
         /* First, try systemd via D-Bus. */
         if (start_unit(0, NULL, NULL) >= 0)
                 return 0;
@@ -8311,7 +8290,6 @@ static int start_with_fallback(void) {
 }
 
 static int halt_now(enum action a) {
-
         /* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need to be
          * synce'd explicitly in advance. */
         if (!arg_no_sync && !arg_dry_run)
@@ -8442,6 +8420,11 @@ static int halt_main(void) {
                 }
         }
 
+        /* In order to minimize the difference between operation with and
+         * without logind, we explicitly enable non-blocking mode for this,
+         * as logind's shutdown operations are always non-blocking. */
+        arg_no_block = true;
+
         if (!arg_dry_run && !arg_force)
                 return start_with_fallback();
 
@@ -8582,7 +8565,7 @@ int main(int argc, char*argv[]) {
         case ACTION_SUSPEND:
         case ACTION_HIBERNATE:
         case ACTION_HYBRID_SLEEP:
-        case ACTION_SUSPEND_TO_HIBERNATE:
+        case ACTION_SUSPEND_THEN_HIBERNATE:
         case ACTION_EMERGENCY:
         case ACTION_DEFAULT:
                 /* systemctl verbs with no equivalent in the legacy commands.