chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
systemctl: extend list-units output a little
[elogind.git]
/
src
/
install.c
diff --git
a/src/install.c
b/src/install.c
index 38c0513fad08c19f83d5fd40116427f4a8f02a71..bd23a938f36acf21e82ece810894d6dc808c4ac4 100644
(file)
--- a/
src/install.c
+++ b/
src/install.c
@@
-24,6
+24,7
@@
#include <getopt.h>
#include <errno.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <unistd.h>
+#include <fcntl.h>
#include "log.h"
#include "path-lookup.h"
#include "log.h"
#include "path-lookup.h"
@@
-46,6
+47,7
@@
static enum {
ACTION_INVALID,
ACTION_ENABLE,
ACTION_DISABLE,
ACTION_INVALID,
ACTION_ENABLE,
ACTION_DISABLE,
+ ACTION_REALIZE,
ACTION_TEST
} arg_action = ACTION_INVALID;
ACTION_TEST
} arg_action = ACTION_INVALID;
@@
-81,6
+83,8
@@
static int help(void) {
"Commands:\n"
" enable [NAME...] Enable one or more units\n"
" disable [NAME...] Disable one or more units\n"
"Commands:\n"
" enable [NAME...] Enable one or more units\n"
" disable [NAME...] Disable one or more units\n"
+ " realize [NAME...] Test whether any of the specified units are enabled\n"
+ " and the start/stop/restart units accordingly\n"
" test [NAME...] Test whether any of the specified units are enabled\n",
program_invocation_short_name);
" test [NAME...] Test whether any of the specified units are enabled\n",
program_invocation_short_name);
@@
-108,6
+112,7
@@
static int parse_argv(int argc, char *argv[]) {
};
int c;
};
int c;
+ bool realize_switch = false;
assert(argc >= 1);
assert(argv);
assert(argc >= 1);
assert(argv);
@@
-138,6
+143,8
@@
static int parse_argv(int argc, char *argv[]) {
case ARG_REALIZE:
case ARG_REALIZE:
+ realize_switch = true;
+
if (!optarg)
arg_realize = REALIZE_MAYBE;
else if (streq(optarg, "no"))
if (!optarg)
arg_realize = REALIZE_MAYBE;
else if (streq(optarg, "no"))
@@
-177,7
+184,12
@@
static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_DISABLE;
else if (streq(argv[optind], "test"))
arg_action = ACTION_TEST;
arg_action = ACTION_DISABLE;
else if (streq(argv[optind], "test"))
arg_action = ACTION_TEST;
- else {
+ else if (streq(argv[optind], "realize")) {
+ arg_action = ACTION_REALIZE;
+
+ if (!realize_switch)
+ arg_realize = REALIZE_MAYBE;
+ } else {
log_error("Unknown verb %s.", argv[optind]);
return -EINVAL;
}
log_error("Unknown verb %s.", argv[optind]);
return -EINVAL;
}
@@
-297,7
+309,7
@@
finish:
return r;
}
return r;
}
-static int install_info_run(DBusConnection *bus, InstallInfo *i) {
+static int install_info_run(DBusConnection *bus, InstallInfo *i
, bool enabled
) {
DBusMessage *m = NULL, *reply = NULL;
DBusError error;
int r;
DBusMessage *m = NULL, *reply = NULL;
DBusError error;
int r;
@@
-308,7
+320,8
@@
static int install_info_run(DBusConnection *bus, InstallInfo *i) {
dbus_error_init(&error);
dbus_error_init(&error);
- if (arg_action == ACTION_ENABLE) {
+ if (arg_action == ACTION_ENABLE ||
+ (arg_action == ACTION_REALIZE && enabled)) {
if (arg_realize == REALIZE_MAYBE) {
char **k;
if (arg_realize == REALIZE_MAYBE) {
char **k;
@@
-436,7
+449,8
@@
static int install_info_run(DBusConnection *bus, InstallInfo *i) {
}
}
- } else if (arg_action == ACTION_DISABLE) {
+ } else if (arg_action == ACTION_DISABLE ||
+ (arg_action == ACTION_REALIZE && !enabled)) {
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
@@
-456,10
+470,11
@@
static int install_info_run(DBusConnection *bus, InstallInfo *i) {
r = -ENOMEM;
goto finish;
}
r = -ENOMEM;
goto finish;
}
- }
+ } else
+ assert_not_reached("install_info_run() called but nothing to do?");
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to re
load configuration
: %s", error.message);
+ log_error("Failed to re
alize unit
: %s", error.message);
r = -EIO;
goto finish;
}
r = -EIO;
goto finish;
}
@@
-591,7
+606,7
@@
static int create_symlink(const char *old_path, const char *new_path) {
log_error("Cannot unlink %s: %m", new_path);
return -errno;
log_error("Cannot unlink %s: %m", new_path);
return -errno;
- } else if (arg_action == ACTION_TEST) {
+ } else if (arg_action == ACTION_TEST
|| arg_action == ACTION_REALIZE
) {
char *dest;
if ((r = readlink_and_make_absolute(new_path, &dest)) < 0) {
char *dest;
if ((r = readlink_and_make_absolute(new_path, &dest)) < 0) {
@@
-708,22
+723,32
@@
static int install_info_apply(LookupPaths *paths, InstallInfo *i, const char *co
assert(i);
STRV_FOREACH(p, paths->unit_path) {
assert(i);
STRV_FOREACH(p, paths->unit_path) {
+ int fd;
if (!(filename = path_make_absolute(i->name, *p))) {
log_error("Out of memory");
return -ENOMEM;
}
if (!(filename = path_make_absolute(i->name, *p))) {
log_error("Out of memory");
return -ENOMEM;
}
- if ((f = fopen(filename, "re")))
- break;
+ /* Ensure that we don't follow symlinks */
+ if ((fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NOCTTY)) >= 0)
+ if ((f = fdopen(fd, "re")))
+ break;
- free(filename);
- filename = NULL;
+ if (errno == ELOOP) {
+ log_error("Refusing to operate on symlinks, please pass unit names or absolute paths to unit files.");
+ free(filename);
+ return -errno;
+ }
if (errno != ENOENT) {
log_error("Failed to open %s: %m", filename);
if (errno != ENOENT) {
log_error("Failed to open %s: %m", filename);
+ free(filename);
return -errno;
}
return -errno;
}
+
+ free(filename);
+ filename = NULL;
}
if (!f) {
}
if (!f) {
@@
-773,7
+798,7
@@
static char *get_config_path(void) {
}
}
}
}
-static int do_realize(
voi
d) {
+static int do_realize(
bool enable
d) {
DBusConnection *bus = NULL;
DBusError error;
int r, q;
DBusConnection *bus = NULL;
DBusError error;
int r, q;
@@
-790,13
+815,13
@@
static int do_realize(void) {
return 0;
}
return 0;
}
- if (arg_action
!= ACTION_ENABLE && arg_action != ACTION_DISABLE
) {
+ if (arg_action
== ACTION_TEST
) {
log_warning("Warning: --realize has no effect with test.");
return 0;
}
if (arg_where == WHERE_SYSTEM && sd_booted() <= 0) {
log_warning("Warning: --realize has no effect with test.");
return 0;
}
if (arg_where == WHERE_SYSTEM && sd_booted() <= 0) {
- log_info("systemd is not running, --realize has no
t
effect.");
+ log_info("systemd is not running, --realize has no effect.");
return 0;
}
return 0;
}
@@
-812,13
+837,13
@@
static int do_realize(void) {
r = 0;
r = 0;
- if (arg_action == ACTION_ENABLE)
+ if (arg_action == ACTION_ENABLE
|| arg_action == ACTION_REALIZE
)
if ((r = daemon_reload(bus)) < 0)
goto finish;
if (arg_realize != REALIZE_RELOAD) {
HASHMAP_FOREACH(j, have_installed, i)
if ((r = daemon_reload(bus)) < 0)
goto finish;
if (arg_realize != REALIZE_RELOAD) {
HASHMAP_FOREACH(j, have_installed, i)
- if ((q = install_info_run(bus, j)) < 0)
+ if ((q = install_info_run(bus, j
, enabled
)) < 0)
r = q;
}
r = q;
}
@@
-887,15
+912,13
@@
int main(int argc, char *argv[]) {
/* In test mode and found something */
retval = 0;
/* In test mode and found something */
retval = 0;
-
goto finish
;
+
break
;
}
}
}
}
- if (do_realize() < 0)
+ if (do_realize(
!retval
) < 0)
goto finish;
goto finish;
- retval = arg_action == ACTION_TEST ? 1 : 0;
-
finish:
install_info_hashmap_free(will_install);
install_info_hashmap_free(have_installed);
finish:
install_info_hashmap_free(will_install);
install_info_hashmap_free(have_installed);