#include <sys/socket.h>
#include <sys/stat.h>
#include <stddef.h>
+#include <sys/prctl.h>
#include <dbus/dbus.h>
static char **arg_property = NULL;
static bool arg_all = false;
static bool arg_fail = false;
-static bool arg_session = false;
+static bool arg_user = false;
static bool arg_global = false;
static bool arg_immediate = false;
static bool arg_no_block = false;
static bool arg_full = false;
static bool arg_force = false;
static bool arg_defaults = false;
+static bool arg_ask_password = false;
static char **arg_wall = NULL;
+static const char *arg_kill_who = NULL;
+static const char *arg_kill_mode = NULL;
+static int arg_signal = SIGTERM;
static usec_t arg_when = 0;
static enum action {
ACTION_INVALID,
ACTION_HALT,
ACTION_POWEROFF,
ACTION_REBOOT,
+ ACTION_KEXEC,
+ ACTION_EXIT,
ACTION_RUNLEVEL2,
ACTION_RUNLEVEL3,
ACTION_RUNLEVEL4,
return t;
}
+static void spawn_ask_password_agent(void) {
+ pid_t parent, child;
+
+ /* We check STDIN here, not STDOUT, since this is about input,
+ * not output */
+ if (!isatty(STDIN_FILENO))
+ return;
+
+ if (!arg_ask_password)
+ return;
+
+ parent = getpid();
+
+ /* Spawns a temporary TTY agent, making sure it goes away when
+ * we go away */
+
+ if ((child = fork()) < 0)
+ return;
+
+ if (child == 0) {
+ /* In the child */
+
+ const char * const args[] = {
+ SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH,
+ "--watch",
+ NULL
+ };
+
+ if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
+ _exit(EXIT_FAILURE);
+
+ /* Check whether our parent died before we were able
+ * to set the death signal */
+ if (getppid() != parent)
+ _exit(EXIT_SUCCESS);
+
+ execv(args[0], (char **) args);
+ _exit(EXIT_FAILURE);
+ }
+}
+
static const char *ansi_highlight(bool b) {
if (!on_tty())
[ACTION_HALT] = "The system is going down for system halt NOW!",
[ACTION_REBOOT] = "The system is going down for reboot NOW!",
[ACTION_POWEROFF] = "The system is going down for power-off NOW!",
+ [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
[ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
[ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!"
};
}
if (*p) {
- utmp_wall(p);
+ utmp_wall(p, NULL);
free(p);
return;
}
if (!table[action])
return;
- utmp_wall(table[action]);
+ utmp_wall(table[action], NULL);
}
struct unit_info {
}
static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
- unsigned active_len, sub_len, job_len;
+ unsigned active_len, sub_len, job_len, n_shown = 0;
const struct unit_info *u;
active_len = sizeof("ACTIVE")-1;
if (!output_show_job(u))
continue;
+ n_shown++;
+
if (!streq(u->load_state, "loaded") &&
!streq(u->load_state, "banned")) {
on_loaded = ansi_highlight(true);
"JOB = Pending job for the unit.\n");
if (arg_all)
- printf("\n%u units listed.\n", c);
+ printf("\n%u units listed.\n", n_shown);
else
- printf("\n%u units listed. Pass --all to see inactive units, too.\n", c);
+ printf("\n%u units listed. Pass --all to see inactive units, too.\n", n_shown);
}
}
;
if (!arg_quiet && d.failed)
- log_error("Job failed, see system logs for details.");
+ log_error("Job failed. See system logs and 'systemctl status' for details.");
r = d.failed ? -EIO : 0;
if (need_daemon_reload(bus, name))
log_warning("Unit file of created job changed on disk, 'systemctl %s daemon-reload' recommended.",
- arg_session ? "--session" : "--system");
+ arg_user ? "--user" : "--system");
if (!arg_no_block) {
char *p;
return ACTION_POWEROFF;
else if (streq(verb, "reboot"))
return ACTION_REBOOT;
+ else if (streq(verb, "kexec"))
+ return ACTION_KEXEC;
else if (streq(verb, "rescue"))
return ACTION_RESCUE;
else if (streq(verb, "emergency"))
return ACTION_EMERGENCY;
else if (streq(verb, "default"))
return ACTION_DEFAULT;
+ else if (streq(verb, "exit"))
+ return ACTION_EXIT;
else
return ACTION_INVALID;
}
[ACTION_HALT] = SPECIAL_HALT_TARGET,
[ACTION_POWEROFF] = SPECIAL_POWEROFF_TARGET,
[ACTION_REBOOT] = SPECIAL_REBOOT_TARGET,
+ [ACTION_KEXEC] = SPECIAL_KEXEC_TARGET,
[ACTION_RUNLEVEL2] = SPECIAL_RUNLEVEL2_TARGET,
[ACTION_RUNLEVEL3] = SPECIAL_RUNLEVEL3_TARGET,
[ACTION_RUNLEVEL4] = SPECIAL_RUNLEVEL4_TARGET,
[ACTION_RUNLEVEL5] = SPECIAL_RUNLEVEL5_TARGET,
[ACTION_RESCUE] = SPECIAL_RESCUE_TARGET,
[ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET,
- [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET
+ [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET,
+ [ACTION_EXIT] = SPECIAL_EXIT_TARGET
};
int r, ret = 0;
assert(bus);
+ spawn_ask_password_agent();
+
if (arg_action == ACTION_SYSTEMCTL) {
method =
streq(args[0], "stop") ? "StopUnit" :
assert(bus);
assert(args);
+ if (arg_force &&
+ (streq(args[0], "halt") ||
+ streq(args[0], "poweroff") ||
+ streq(args[0], "reboot") ||
+ streq(args[0], "kexec") ||
+ streq(args[0], "exit")))
+ return daemon_reload(bus, args, n);
+
r = start_unit(bus, args, n);
if (r >= 0)
puts("unknown");
dbus_error_free(&error);
+ dbus_message_unref(m);
continue;
}
return r;
}
+static int kill_unit(DBusConnection *bus, char **args, unsigned n) {
+ DBusMessage *m = NULL, *reply = NULL;
+ int r = 0;
+ DBusError error;
+ unsigned i;
+
+ assert(bus);
+ assert(args);
+
+ dbus_error_init(&error);
+
+ if (!arg_kill_who)
+ arg_kill_who = "all";
+
+ if (!arg_kill_mode)
+ arg_kill_mode = streq(arg_kill_who, "all") ? "control-group" : "process";
+
+ for (i = 1; i < n; i++) {
+
+ if (!(m = dbus_message_new_method_call(
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "KillUnit"))) {
+ log_error("Could not allocate message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_STRING, &args[i],
+ DBUS_TYPE_STRING, &arg_kill_who,
+ DBUS_TYPE_STRING, &arg_kill_mode,
+ DBUS_TYPE_INT32, &arg_signal,
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ dbus_error_free(&error);
+ r = -EIO;
+ }
+
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+ m = reply = NULL;
+ }
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ return r;
+}
+
typedef struct ExecStatusInfo {
char *path;
char **argv;
const char *sub_state;
const char *description;
+ const char *following;
const char *path;
const char *default_control_group;
printf("\n");
+ if (i->following)
+ printf("\t Follow: unit currently follows state of %s\n", i->following);
+
if (streq_ptr(i->load_state, "failed") ||
streq_ptr(i->load_state, "banned")) {
on = ansi_highlight(true);
s2 = format_timestamp(since2, sizeof(since2), timestamp);
if (s1)
- printf(" since [%s; %s]\n", s2, s1);
+ printf(" since %s; %s\n", s2, s1);
else if (s2)
- printf(" since [%s]\n", s2);
+ printf(" since %s\n", s2);
else
printf("\n");
if (i->sysfs_path)
printf("\t Device: %s\n", i->sysfs_path);
- else if (i->where)
+ if (i->where)
printf("\t Where: %s\n", i->where);
- else if (i->what)
+ if (i->what)
printf("\t What: %s\n", i->what);
if (i->accept)
printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %s daemon-reload' recommended.\n",
ansi_highlight(true),
ansi_highlight(false),
- arg_session ? "--session" : "--system");
+ arg_user ? "--user" : "--system");
}
static int status_property(const char *name, DBusMessageIter *iter, UnitStatusInfo *i) {
i->where = s;
else if (streq(name, "What"))
i->what = s;
+ else if (streq(name, "Following"))
+ i->following = s;
}
break;
return 0;
}
-static int show_one(DBusConnection *bus, const char *path, bool show_properties, bool *new_line) {
+static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) {
DBusMessage *m = NULL, *reply = NULL;
const char *interface = "";
int r;
print_status_info(&info);
if (!streq_ptr(info.active_state, "active") &&
- !streq_ptr(info.active_state, "reloading"))
+ !streq_ptr(info.active_state, "reloading") &&
+ streq(verb, "status"))
/* According to LSB: "program not running" */
r = 3;
/* If not argument is specified inspect the manager
* itself */
- ret = show_one(bus, "/org/freedesktop/systemd1", show_properties, &new_line);
+ ret = show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line);
goto finish;
}
goto finish;
}
- if ((r = show_one(bus, path, show_properties, &new_line)) != 0)
+ if ((r = show_one(args[0], bus, path, show_properties, &new_line)) != 0)
ret = r;
dbus_message_unref(m);
assert(arg_action == ACTION_SYSTEMCTL);
method =
- streq(args[0], "clear-jobs") ||
- streq(args[0], "cancel") ? "ClearJobs" :
- streq(args[0], "daemon-reexec") ? "Reexecute" :
- streq(args[0], "reset-failed") ? "ResetFailed" :
- streq(args[0], "daemon-exit") ? "Exit" :
- "Reload";
+ streq(args[0], "clear-jobs") ||
+ streq(args[0], "cancel") ? "ClearJobs" :
+ streq(args[0], "daemon-reexec") ? "Reexecute" :
+ streq(args[0], "reset-failed") ? "ResetFailed" :
+ streq(args[0], "halt") ? "Halt" :
+ streq(args[0], "poweroff") ? "PowerOff" :
+ streq(args[0], "reboot") ? "Reboot" :
+ streq(args[0], "kexec") ? "KExec" :
+ streq(args[0], "exit") ? "Exit" :
+ /* "daemon-reload" */ "Reload";
}
if (!(m = dbus_message_new_method_call(
static Hashmap *will_install = NULL, *have_installed = NULL;
static Set *remove_symlinks_to = NULL;
+static unsigned n_symlinks = 0;
static void install_info_free(InstallInfo *i) {
assert(i);
assert(will_install);
- if (!unit_name_is_valid_no_type(name)) {
+ if (!unit_name_is_valid_no_type(name, true)) {
log_warning("Unit name %s is not a valid unit name.", name);
return -EINVAL;
}
STRV_FOREACH(s, i->aliases) {
- if (!unit_name_is_valid_no_type(*s)) {
- log_error("Invalid name %s.", *s);
- r = -EINVAL;
- goto finish;
- }
-
free(alias_path);
if (!(alias_path = path_make_absolute(*s, config_path))) {
log_error("Out of memory");
assert(config_path);
STRV_FOREACH(s, i->wanted_by) {
- if (!unit_name_is_valid_no_type(*s)) {
+ if (!unit_name_is_valid_no_type(*s, true)) {
log_error("Invalid name %s.", *s);
r = -EINVAL;
goto finish;
}
if (!f) {
+#if defined(TARGET_FEDORA) && defined (HAVE_SYSV_COMPAT)
+
+ if (endswith(i->name, ".service")) {
+ char *sysv;
+ bool exists;
+
+ if (asprintf(&sysv, SYSTEM_SYSVINIT_PATH "/%s", i->name) < 0) {
+ log_error("Out of memory");
+ return -ENOMEM;
+ }
+
+ sysv[strlen(sysv) - sizeof(".service") + 1] = 0;
+ exists = access(sysv, F_OK) >= 0;
+
+ if (exists) {
+ pid_t pid;
+ siginfo_t status;
+
+ const char *argv[] = {
+ "/sbin/chkconfig",
+ NULL,
+ NULL,
+ NULL
+ };
+
+ log_info("%s is not a native service, redirecting to /sbin/chkconfig.", i->name);
+
+ argv[1] = file_name_from_path(sysv);
+ argv[2] =
+ streq(verb, "enable") ? "on" :
+ streq(verb, "disable") ? "off" : NULL;
+
+ log_info("Executing %s %s %s", argv[0], argv[1], strempty(argv[2]));
+
+ if ((pid = fork()) < 0) {
+ log_error("Failed to fork: %m");
+ free(sysv);
+ return -errno;
+ } else if (pid == 0) {
+ execv(argv[0], (char**) argv);
+ _exit(EXIT_FAILURE);
+ }
+
+ free(sysv);
+
+ if ((r = wait_for_terminate(pid, &status)) < 0)
+ return r;
+
+ if (status.si_code == CLD_EXITED) {
+ if (status.si_status == 0 && (streq(verb, "enable") || streq(verb, "disable")))
+ n_symlinks ++;
+
+ return status.si_status == 0 ? 0 : -EINVAL;
+ } else
+ return -EPROTO;
+ }
+
+ free(sysv);
+ }
+
+#endif
+
log_error("Couldn't find %s.", i->name);
return -ENOENT;
}
return r;
}
+ n_symlinks += strv_length(i->aliases);
+ n_symlinks += strv_length(i->wanted_by);
+
fclose(f);
if ((r = install_info_symlink_alias(verb, i, config_path)) != 0)
static char *get_config_path(void) {
- if (arg_session && arg_global)
- return strdup(SESSION_CONFIG_UNIT_PATH);
+ if (arg_user && arg_global)
+ return strdup(USER_CONFIG_UNIT_PATH);
- if (arg_session) {
+ if (arg_user) {
char *p;
- if (session_config_home(&p) < 0)
+ if (user_config_home(&p) < 0)
return NULL;
return p;
dbus_error_init(&error);
zero(paths);
- if ((r = lookup_paths_init(&paths, arg_session ? MANAGER_SESSION : MANAGER_SYSTEM)) < 0) {
+ if ((r = lookup_paths_init(&paths, arg_user ? MANAGER_USER : MANAGER_SYSTEM)) < 0) {
log_error("Failed to determine lookup paths: %s", strerror(-r));
goto finish;
}
if (streq(verb, "is-enabled"))
r = r > 0 ? 0 : -ENOENT;
- else if (bus &&
- /* Don't try to reload anything if the user asked us to not do this */
- !arg_no_reload &&
- /* Don't try to reload anything when updating a unit globally */
- !arg_global &&
- /* Don't try to reload anything if we are called for system changes but the system wasn't booted with systemd */
- (arg_session || sd_booted() > 0) &&
- /* Don't try to reload anything if we are running in a chroot environment */
- (arg_session || running_in_chroot() <= 0) ) {
- int q;
+ else {
+ if (n_symlinks <= 0)
+ log_warning("Unit files contain no applicable installation information. Ignoring.");
+
+ if (bus &&
+ /* Don't try to reload anything if the user asked us to not do this */
+ !arg_no_reload &&
+ /* Don't try to reload anything when updating a unit globally */
+ !arg_global &&
+ /* Don't try to reload anything if we are called for system changes but the system wasn't booted with systemd */
+ (arg_user || sd_booted() > 0) &&
+ /* Don't try to reload anything if we are running in a chroot environment */
+ (arg_user || running_in_chroot() <= 0) ) {
+ int q;
- if ((q = daemon_reload(bus, args, n)) < 0)
- r = q;
+ if ((q = daemon_reload(bus, args, n)) < 0)
+ r = q;
+ }
}
finish:
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
"Send control commands to or query the systemd manager.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " -t --type=TYPE List only units of a particular type\n"
- " -p --property=NAME Show only properties by this name\n"
- " -a --all Show all units/properties, including dead/empty ones\n"
- " --full Don't ellipsize unit names on output\n"
- " --fail When queueing a new job, fail if conflicting jobs are\n"
- " pending\n"
- " -q --quiet Suppress output\n"
- " --no-block Do not wait until operation finished\n"
- " --system Connect to system bus\n"
- " --session Connect to session bus\n"
- " --order When generating graph for dot, show only order\n"
- " --require When generating graph for dot, show only requirement\n"
- " --no-wall Don't send wall message before halt/power-off/reboot\n"
- " --global Enable/disable unit files globally\n"
- " --no-reload When enabling/disabling unit files, don't reload daemon\n"
- " configuration\n"
- " --force When enabling unit files, override existing symlinks\n"
- " --defaults When disabling unit files, remove default symlinks only\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " -t --type=TYPE List only units of a particular type\n"
+ " -p --property=NAME Show only properties by this name\n"
+ " -a --all Show all units/properties, including dead/empty ones\n"
+ " --full Don't ellipsize unit names on output\n"
+ " --fail When queueing a new job, fail if conflicting jobs are\n"
+ " pending\n"
+ " -q --quiet Suppress output\n"
+ " --no-block Do not wait until operation finished\n"
+ " --system Connect to system manager\n"
+ " --user Connect to user service manager\n"
+ " --order When generating graph for dot, show only order\n"
+ " --require When generating graph for dot, show only requirement\n"
+ " --no-wall Don't send wall message before halt/power-off/reboot\n"
+ " --global Enable/disable unit files globally\n"
+ " --no-reload When enabling/disabling unit files, don't reload daemon\n"
+ " configuration\n"
+ " --no-ask-password\n"
+ " Do not ask for system passwords\n"
+ " --kill-mode=MODE How to send signal\n"
+ " --kill-who=WHO Who to send signal to\n"
+ " -s --signal=SIGNAL Which signal to send\n"
+ " -f --force When enabling unit files, override existing symlinks\n"
+ " When shutting down, execute action immediately\n"
+ " --defaults When disabling unit files, remove default symlinks only\n\n"
"Commands:\n"
" list-units List units\n"
" start [NAME...] Start (activate) one or more units\n"
" reload-or-try-restart [NAME...] Reload one or more units is possible,\n"
" otherwise restart if active\n"
" isolate [NAME] Start one unit and stop all others\n"
+ " kill [NAME...] Send signal to processes of a unit\n"
" is-active [NAME...] Check whether units are active\n"
" status [NAME...|PID...] Show runtime status of one or more units\n"
" show [NAME...|JOB...] Show properties of one or more\n"
" delete [NAME...] Remove one or more snapshots\n"
" daemon-reload Reload systemd manager configuration\n"
" daemon-reexec Reexecute systemd manager\n"
- " daemon-exit Ask the systemd manager to quit\n"
" show-environment Dump environment\n"
" set-environment [NAME=VALUE...] Set one or more environment variables\n"
" unset-environment [NAME...] Unset one or more environment variables\n"
+ " default Enter system default mode\n"
+ " rescue Enter system rescue mode\n"
+ " emergency Enter system emergency mode\n"
" halt Shut down and halt the system\n"
" poweroff Shut down and power-off the system\n"
" reboot Shut down and reboot the system\n"
- " rescue Enter system rescue mode\n"
- " emergency Enter system emergency mode\n"
- " default Enter system default mode\n",
+ " kexec Shut down and reboot the system with kexec\n"
+ " exit Ask for user instance termination\n",
program_invocation_short_name);
return 0;
enum {
ARG_FAIL = 0x100,
ARG_VERSION,
- ARG_SESSION,
+ ARG_USER,
ARG_SYSTEM,
ARG_GLOBAL,
ARG_NO_BLOCK,
ARG_ORDER,
ARG_REQUIRE,
ARG_FULL,
- ARG_FORCE,
ARG_NO_RELOAD,
- ARG_DEFAULTS
+ ARG_DEFAULTS,
+ ARG_KILL_MODE,
+ ARG_KILL_WHO,
+ ARG_NO_ASK_PASSWORD
};
static const struct option options[] = {
{ "all", no_argument, NULL, 'a' },
{ "full", no_argument, NULL, ARG_FULL },
{ "fail", no_argument, NULL, ARG_FAIL },
- { "session", no_argument, NULL, ARG_SESSION },
+ { "user", no_argument, NULL, ARG_USER },
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "global", no_argument, NULL, ARG_GLOBAL },
{ "no-block", no_argument, NULL, ARG_NO_BLOCK },
{ "quiet", no_argument, NULL, 'q' },
{ "order", no_argument, NULL, ARG_ORDER },
{ "require", no_argument, NULL, ARG_REQUIRE },
- { "force", no_argument, NULL, ARG_FORCE },
+ { "force", no_argument, NULL, 'f' },
{ "no-reload", no_argument, NULL, ARG_NO_RELOAD },
{ "defaults", no_argument, NULL, ARG_DEFAULTS },
+ { "kill-mode", required_argument, NULL, ARG_KILL_MODE },
+ { "kill-who", required_argument, NULL, ARG_KILL_WHO },
+ { "signal", required_argument, NULL, 's' },
+ { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
{ NULL, 0, NULL, 0 }
};
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "ht:p:aq", options, NULL)) >= 0) {
+ /* Only when running as systemctl we ask for passwords */
+ arg_ask_password = true;
+
+ while ((c = getopt_long(argc, argv, "ht:p:aqfs:", options, NULL)) >= 0) {
switch (c) {
arg_fail = true;
break;
- case ARG_SESSION:
- arg_session = true;
+ case ARG_USER:
+ arg_user = true;
break;
case ARG_SYSTEM:
- arg_session = false;
+ arg_user = false;
break;
case ARG_NO_BLOCK:
arg_quiet = true;
break;
- case ARG_FORCE:
+ case 'f':
arg_force = true;
break;
case ARG_GLOBAL:
arg_global = true;
- arg_session = true;
+ arg_user = true;
break;
case ARG_DEFAULTS:
arg_defaults = true;
break;
+ case ARG_KILL_WHO:
+ arg_kill_who = optarg;
+ break;
+
+ case ARG_KILL_MODE:
+ arg_kill_mode = optarg;
+ break;
+
+ case 's':
+ if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
+ log_error("Failed to parse signal string %s.", optarg);
+ return -EINVAL;
+ }
+ break;
+
+ case ARG_NO_ASK_PASSWORD:
+ arg_ask_password = false;
+ break;
+
case '?':
return -EINVAL;
{ "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
{ "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
{ "isolate", EQUAL, 2, start_unit },
+ { "kill", MORE, 2, kill_unit },
{ "is-active", MORE, 2, check_unit },
{ "check", MORE, 2, check_unit },
{ "show", MORE, 1, show },
{ "delete", MORE, 2, delete_snapshot },
{ "daemon-reload", EQUAL, 1, daemon_reload },
{ "daemon-reexec", EQUAL, 1, daemon_reload },
- { "daemon-exit", EQUAL, 1, daemon_reload },
{ "show-environment", EQUAL, 1, show_enviroment },
{ "set-environment", MORE, 2, set_environment },
{ "unset-environment", MORE, 2, set_environment },
{ "halt", EQUAL, 1, start_special },
{ "poweroff", EQUAL, 1, start_special },
{ "reboot", EQUAL, 1, start_special },
+ { "kexec", EQUAL, 1, start_special },
{ "default", EQUAL, 1, start_special },
{ "rescue", EQUAL, 1, start_special },
{ "emergency", EQUAL, 1, start_special },
+ { "exit", EQUAL, 1, start_special },
{ "reset-failed", MORE, 1, reset_failed },
{ "enable", MORE, 2, enable_unit },
{ "disable", MORE, 2, enable_unit },
goto finish;
}
- bus_connect(arg_session ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &private_bus, &error);
+ bus_connect(arg_user ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &private_bus, &error);
switch (arg_action) {