diff options
author | Lennart Poettering <lennart@poettering.net> | 2017-11-22 15:03:51 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2017-11-29 12:34:12 +0100 |
commit | 2e59b241ca86b8338c706a7a704d301fde908581 (patch) | |
tree | 4f83e31ad02c6c691ff712a8a4499533c63dd720 /src/core/dbus-unit.c | |
parent | ddd59d0c7ffc77158ab2d6f52f08812670bb9160 (diff) | |
download | systemd-2e59b241ca86b8338c706a7a704d301fde908581.tar.gz |
core: add proper escaping to writing of drop-ins/transient unit files
This majorly refactors the transient unit file and drop-in writing
logic, so that we properly C-escape and specifier-escape (% → %%)
everything we write out, so that when we read it back again, specifiers
are parsed that aren't supposed to be parsed.
This renames unit_write_drop_in() and friends by unit_write_setting().
The name change is supposed to clarify that the functions are not only
used to write drop-in files, but also transient unit files.
The previous "mode" parameter to this function is replaced by a more
generic "flags", which knows additional flags for implicit C-style and
specifier escaping before writing things out. This can cover most
properties where either form of escaping is defined. For the cases where
this isn't sufficient, we add helpers unit_escape_setting() and
unit_concat_strv() for escaping individual strings or strvs properly.
While we are at it, we also prettify generation of transient unit files:
we try to reduce the number of section headers written out: previously
we'd write the right section header our for each setting. With this
change we do so only if the setting lives in a different section than
the one before.
(This should also be considered preparation for when we add proper APIs
to systemd to write normal, persistant unit files through the bus API)
Diffstat (limited to 'src/core/dbus-unit.c')
-rw-r--r-- | src/core/dbus-unit.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index d4bdf1760a..5d4bc28cde 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -1319,7 +1319,7 @@ static int bus_unit_set_transient_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { int r; @@ -1335,12 +1335,12 @@ static int bus_unit_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = unit_set_description(u, d); if (r < 0) return r; - unit_write_drop_in_format(u, mode, name, "[Unit]\nDescription=%s", d); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Description=%s", d); } return 1; @@ -1352,9 +1352,9 @@ static int bus_unit_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { u->default_dependencies = b; - unit_write_drop_in_format(u, mode, name, "[Unit]\nDefaultDependencies=%s", yes_no(b)); + unit_write_settingf(u, flags, name, "DefaultDependencies=%s", yes_no(b)); } return 1; @@ -1371,9 +1371,9 @@ static int bus_unit_set_transient_property( if (m < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown garbage collection mode: %s", s); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { u->collect_mode = m; - unit_write_drop_in_format(u, mode, name, "[Unit]\nCollectMode=%s", collect_mode_to_string(m)); + unit_write_settingf(u, flags, name, "CollectMode=%s", collect_mode_to_string(m)); } return 1; @@ -1406,12 +1406,12 @@ static int bus_unit_set_transient_property( if (slice->type != UNIT_SLICE) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit name '%s' is not a slice", s); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = unit_set_slice(u, slice); if (r < 0) return r; - unit_write_drop_in_private_format(u, mode, name, "Slice=%s", s); + unit_write_settingf(u, flags|UNIT_PRIVATE, name, "Slice=%s", s); } return 1; @@ -1448,7 +1448,7 @@ static int bus_unit_set_transient_property( if (!unit_name_is_valid(other, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name %s", other); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *label = NULL; r = unit_add_dependency_by_name(u, d, other, NULL, true, UNIT_DEPENDENCY_FILE); @@ -1459,7 +1459,7 @@ static int bus_unit_set_transient_property( if (!label) return -ENOMEM; - unit_write_drop_in_format(u, mode, label, "[Unit]\n%s=%s", name, other); + unit_write_settingf(u, flags, label, "%s=%s", name, other); } } @@ -1484,14 +1484,14 @@ static int bus_unit_set_transient_property( if (action < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid emergency action: %s", s); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "FailureAction")) u->failure_action = action; else u->success_action = action; - unit_write_drop_in_format(u, mode, name, "%s=%s", name, emergency_action_to_string(action)); + unit_write_settingf(u, flags, name, "%s=%s", name, emergency_action_to_string(action)); } return 1; @@ -1514,7 +1514,7 @@ static int bus_unit_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) + if (!UNIT_WRITE_FLAGS_NOOP(flags)) u->bus_track_add = b; return 1; @@ -1526,7 +1526,7 @@ static int bus_unit_set_transient_property( int bus_unit_set_properties( Unit *u, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, bool commit, sd_bus_error *error) { @@ -1548,12 +1548,13 @@ int bus_unit_set_properties( for (;;) { const char *name; + UnitWriteFlags f; r = sd_bus_message_enter_container(message, 'r', "sv"); if (r < 0) return r; if (r == 0) { - if (for_real || mode == UNIT_CHECK) + if (for_real || UNIT_WRITE_FLAGS_NOOP(flags)) break; /* Reached EOF. Let's try again, and this time for realz... */ @@ -1576,9 +1577,12 @@ int bus_unit_set_properties( if (r < 0) return r; - r = UNIT_VTABLE(u)->bus_set_property(u, name, message, for_real ? mode : UNIT_CHECK, error); + /* If not for real, then mask out the two target flags */ + f = for_real ? flags : (flags & ~(UNIT_RUNTIME|UNIT_PERSISTENT)); + + r = UNIT_VTABLE(u)->bus_set_property(u, name, message, f, error); if (r == 0 && u->transient && u->load_state == UNIT_STUB) - r = bus_unit_set_transient_property(u, name, message, for_real ? mode : UNIT_CHECK, error); + r = bus_unit_set_transient_property(u, name, message, f, error); if (r < 0) return r; if (r == 0) |