/* 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>
ACTION_SUSPEND,
ACTION_HIBERNATE,
ACTION_HYBRID_SLEEP,
- ACTION_SUSPEND_TO_HIBERNATE,
+ ACTION_SUSPEND_THEN_HIBERNATE,
ACTION_RUNLEVEL2,
ACTION_RUNLEVEL3,
ACTION_RUNLEVEL4,
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
}
static void ask_password_agent_open_if_enabled(void) {
-
/* Open the password agent as a child process if necessary */
if (arg_dry_run)
}
static bool install_client_side(void) {
-
/* Decides when to execute enable/disable/... operations
* client-side rather than server-side. */
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;
}
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;
if (r < 0)
return bus_log_parse_error(r);
- *_reply = reply;
- reply = NULL;
+ *_reply = TAKE_PTR(reply);
return c;
}
}
}
- *_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;
}
.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),
}
static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
-
struct DependencyStatusInfo {
char **dep[5];
} info = {};
"org.freedesktop.systemd1",
path,
map[arg_dependency],
+ BUS_MAP_STRDUP,
&error,
NULL,
&info);
info.dep[i] = strv_free(info.dep[i]);
}
- *deps = ret;
- ret = NULL;
+ *deps = TAKE_PTR(ret);
return 0;
}
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");
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;
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++;
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");
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;
}
if (r < 0)
return r;
- if (template) {
- *template = _template;
- _template = NULL;
- }
+ if (template)
+ *template = TAKE_PTR(_template);
+
return r;
}
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:
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",
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");
}
}
- *ret = mangled;
- mangled = NULL; /* do not free */
+ *ret = TAKE_PTR(mangled);
return 0;
}
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) {
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;
ACTION_SUSPEND,
ACTION_HIBERNATE,
ACTION_HYBRID_SLEEP,
- ACTION_SUSPEND_TO_HIBERNATE)) {
+ ACTION_SUSPEND_THEN_HIBERNATE)) {
r = logind_reboot(a);
if (r >= 0)
/* Socket */
unsigned n_accepted;
unsigned n_connections;
+ unsigned n_refused;
bool accept;
/* Pairs of type, path */
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;
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) &&
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);
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" : ", ");
}
}
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;
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);
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;
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)
{ "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) },
"org.freedesktop.systemd1",
path,
show_mode == SYSTEMCTL_SHOW_STATUS ? status_map : property_map,
+ BUS_MAP_BOOLEAN_AS_BOOL,
&error,
&reply,
&info);
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));
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;
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)
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;
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");
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)
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 */
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);
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));
_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;
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)
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)
_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");
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()) {
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;
}
static int unit_is_enabled(int argc, char *argv[], void *userdata) {
-
_cleanup_strv_free_ char **names = NULL;
bool enabled;
char **name;
} 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;
}
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;
}
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;
}
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;
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;
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);
}
static void systemctl_help(void) {
-
(void) pager_open(arg_no_pager, false);
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
" 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);
}
}
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,
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;
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);
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) {
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,
}
static int shutdown_parse_argv(int argc, char *argv[]) {
-
enum {
ARG_HELP = 0x100,
ARG_NO_WALL
}
static int telinit_parse_argv(int argc, char *argv[]) {
-
enum {
ARG_HELP = 0x100,
ARG_NO_WALL
}
static int runlevel_parse_argv(int argc, char *argv[]) {
-
enum {
ARG_HELP = 0x100,
};
#if HAVE_SYSV_COMPAT
_pure_ static int action_to_runlevel(void) {
-
static const char table[_ACTION_MAX] = {
[ACTION_HALT] = '0',
[ACTION_POWEROFF] = '0',
_cleanup_close_ int fd = -1;
char rl;
int r;
+ const char *p;
rl = action_to_runlevel();
if (!rl)
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
}
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 },
{ "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 },
}
static int reload_with_fallback(void) {
-
/* First, try systemd via D-Bus. */
if (daemon_reload(0, NULL, NULL) >= 0)
return 0;
}
static int start_with_fallback(void) {
-
/* First, try systemd via D-Bus. */
if (start_unit(0, NULL, NULL) >= 0)
return 0;
}
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)
}
}
+ /* 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();
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.