X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsystemctl.c;h=28bdfa96a4e06d9b9c393e7b3357dd96b28f79e8;hb=68fb08920b2162b48cf0fa8dd98b021327b42896;hp=3cab0dd85a073cea185279a62514f34629593db9;hpb=7e59bfcb18bcfdb82fa1f197c935bb15a22aa582;p=elogind.git
diff --git a/src/systemctl.c b/src/systemctl.c
index 3cab0dd85..28bdfa96a 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -6,16 +6,16 @@
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ 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
- General Public License for more details.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see .
***/
@@ -36,6 +36,7 @@
#include
#include
+#include
#include "log.h"
#include "util.h"
@@ -51,13 +52,13 @@
#include "list.h"
#include "path-lookup.h"
#include "conf-parser.h"
-#include "shutdownd.h"
#include "exit-status.h"
#include "bus-errors.h"
#include "build.h"
#include "unit-name.h"
#include "pager.h"
-#include "spawn-agent.h"
+#include "spawn-ask-password-agent.h"
+#include "spawn-polkit-agent.h"
#include "install.h"
#include "logs-show.h"
@@ -78,7 +79,7 @@ static bool arg_dry = false;
static bool arg_quiet = false;
static bool arg_full = false;
static int arg_force = 0;
-static bool arg_ask_password = false;
+static bool arg_ask_password = true;
static bool arg_failed = false;
static bool arg_runtime = false;
static char **arg_wall = NULL;
@@ -154,7 +155,7 @@ static void pager_open_if_enabled(void) {
pager_open();
}
-static void agent_open_if_enabled(void) {
+static void ask_password_agent_open_if_enabled(void) {
/* Open the password agent as a child process if necessary */
@@ -164,7 +165,20 @@ static void agent_open_if_enabled(void) {
if (arg_scope != UNIT_FILE_SYSTEM)
return;
- agent_open();
+ ask_password_agent_open();
+}
+
+static void polkit_agent_open_if_enabled(void) {
+
+ /* Open the polkit agent as a child process if necessary */
+
+ if (!arg_ask_password)
+ return;
+
+ if (arg_scope != UNIT_FILE_SYSTEM)
+ return;
+
+ polkit_agent_open();
}
static const char *ansi_highlight_red(bool b) {
@@ -1601,7 +1615,7 @@ static int start_unit(DBusConnection *bus, char **args) {
assert(bus);
- agent_open_if_enabled();
+ ask_password_agent_open_if_enabled();
if (arg_action == ACTION_SYSTEMCTL) {
method =
@@ -1695,6 +1709,8 @@ static int reboot_with_logind(DBusConnection *bus, enum action a) {
dbus_error_init(&error);
+ polkit_agent_open_if_enabled();
+
switch (a) {
case ACTION_REBOOT:
@@ -4290,9 +4306,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- /* Only when running as systemctl we ask for passwords */
- arg_ask_password = true;
-
while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:Pn:o:", options, NULL)) >= 0) {
switch (c) {
@@ -4628,6 +4641,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
{ "halt", no_argument, NULL, 'H' },
{ "poweroff", no_argument, NULL, 'P' },
{ "reboot", no_argument, NULL, 'r' },
+ { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
{ NULL, 0, NULL, 0 }
};
@@ -4659,6 +4673,10 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
arg_action = ACTION_REBOOT;
break;
+ case 'K':
+ arg_action = ACTION_KEXEC;
+ break;
+
case 'h':
if (arg_action != ACTION_HALT)
arg_action = ACTION_POWEROFF;
@@ -5191,39 +5209,42 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
}
static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
- int fd = -1;
+ int fd;
struct msghdr msghdr;
- struct iovec iovec;
+ struct iovec iovec[2];
union sockaddr_union sockaddr;
- struct shutdownd_command c;
+ struct sd_shutdown_command c;
+
+ fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ return -errno;
zero(c);
- c.elapse = t;
+ c.usec = t;
c.mode = mode;
c.dry_run = dry_run;
c.warn_wall = warn;
- if (message)
- strncpy(c.wall_message, message, sizeof(c.wall_message));
-
- if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0)
- return -errno;
-
zero(sockaddr);
sockaddr.sa.sa_family = AF_UNIX;
- sockaddr.un.sun_path[0] = 0;
strncpy(sockaddr.un.sun_path, "/run/systemd/shutdownd", sizeof(sockaddr.un.sun_path));
- zero(iovec);
- iovec.iov_base = (char*) &c;
- iovec.iov_len = sizeof(c);
-
zero(msghdr);
msghdr.msg_name = &sockaddr;
msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + sizeof("/run/systemd/shutdownd") - 1;
- msghdr.msg_iov = &iovec;
- msghdr.msg_iovlen = 1;
+ zero(iovec);
+ iovec[0].iov_base = (char*) &c;
+ iovec[0].iov_len = offsetof(struct sd_shutdown_command, wall_message);
+
+ if (isempty(message))
+ msghdr.msg_iovlen = 1;
+ else {
+ iovec[1].iov_base = (char*) message;
+ iovec[1].iov_len = strlen(message);
+ msghdr.msg_iovlen = 2;
+ }
+ msghdr.msg_iov = iovec;
if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
close_nointr_nofail(fd);
@@ -5338,6 +5359,7 @@ static int halt_main(DBusConnection *bus) {
r = send_shutdownd(arg_when,
arg_action == ACTION_HALT ? 'H' :
arg_action == ACTION_POWEROFF ? 'P' :
+ arg_action == ACTION_KEXEC ? 'K' :
'r',
arg_dry,
!arg_no_wall,
@@ -5405,7 +5427,8 @@ int main(int argc, char*argv[]) {
log_parse_environment();
log_open();
- if ((r = parse_argv(argc, argv)) < 0)
+ r = parse_argv(argc, argv);
+ if (r < 0)
goto finish;
else if (r == 0) {
retval = EXIT_SUCCESS;
@@ -5493,7 +5516,8 @@ finish:
strv_free(arg_property);
pager_close();
- agent_close();
+ ask_password_agent_close();
+ polkit_agent_close();
return retval;
}