]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/dbus-path.c
Merge pull request #17732 from yuwata/core-use-synthetic_errno
[thirdparty/systemd.git] / src / core / dbus-path.c
index 1e153e503fecad7c6035ef3460a748a087c25a3b..14e77d783dd929b25a17560907c4dcc48d2ae34f 100644 (file)
@@ -1,25 +1,12 @@
-/***
-  This file is part of systemd.
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-  Copyright 2010 Lennart Poettering
-
-  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/>.
-***/
-
-#include "bus-util.h"
+#include "alloc-util.h"
+#include "bus-get-properties.h"
 #include "dbus-path.h"
+#include "dbus-util.h"
+#include "list.h"
 #include "path.h"
+#include "path-util.h"
 #include "string-util.h"
 #include "unit.h"
 
@@ -55,32 +42,118 @@ static int property_get_paths(
         return sd_bus_message_close_container(reply);
 }
 
-static int property_get_unit(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Unit *p = userdata, *trigger;
-
-        assert(bus);
-        assert(reply);
-        assert(p);
-
-        trigger = UNIT_TRIGGER(p);
-
-        return sd_bus_message_append(reply, "s", trigger ? trigger->id : "");
-}
-
 const sd_bus_vtable bus_path_vtable[] = {
         SD_BUS_VTABLE_START(0),
-        SD_BUS_PROPERTY("Unit", "s", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Unit", "s", bus_property_get_triggered_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Paths", "a(ss)", property_get_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("MakeDirectory", "b", bus_property_get_bool, offsetof(Path, make_directory), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Path, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Path, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_VTABLE_END
 };
+
+static int bus_path_set_transient_property(
+                Path *p,
+                const char *name,
+                sd_bus_message *message,
+                UnitWriteFlags flags,
+                sd_bus_error *error) {
+
+        Unit *u = UNIT(p);
+        int r;
+
+        assert(p);
+        assert(name);
+        assert(message);
+
+        flags |= UNIT_PRIVATE;
+
+        if (streq(name, "MakeDirectory"))
+                return bus_set_transient_bool(u, name, &p->make_directory, message, flags, error);
+
+        if (streq(name, "DirectoryMode"))
+                return bus_set_transient_mode_t(u, name, &p->directory_mode, message, flags, error);
+
+        if (streq(name, "Paths")) {
+                const char *type_name, *path;
+                bool empty = true;
+
+                r = sd_bus_message_enter_container(message, 'a', "(ss)");
+                if (r < 0)
+                        return r;
+
+                while ((r = sd_bus_message_read(message, "(ss)", &type_name, &path)) > 0) {
+                        PathType t;
+
+                        t = path_type_from_string(type_name);
+                        if (t < 0)
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown path type: %s", type_name);
+
+                        if (isempty(path))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is empty", type_name);
+
+                        if (!path_is_absolute(path))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is not absolute: %s", type_name, path);
+
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                                _cleanup_free_ char *k;
+                                PathSpec *s;
+
+                                k = strdup(path);
+                                if (!k)
+                                        return -ENOMEM;
+
+                                path_simplify(k, false);
+
+                                s = new0(PathSpec, 1);
+                                if (!s)
+                                        return -ENOMEM;
+
+                                s->unit = u;
+                                s->path = TAKE_PTR(k);
+                                s->type = t;
+                                s->inotify_fd = -1;
+
+                                LIST_PREPEND(spec, p->specs, s);
+
+                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", type_name, path);
+                        }
+
+                        empty = false;
+                }
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_exit_container(message);
+                if (r < 0)
+                        return r;
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
+                        path_free_specs(p);
+                        unit_write_settingf(u, flags, name, "PathExists=");
+                }
+
+                return 1;
+        }
+
+        return 0;
+}
+
+int bus_path_set_property(
+                Unit *u,
+                const char *name,
+                sd_bus_message *message,
+                UnitWriteFlags mode,
+                sd_bus_error *error) {
+
+        Path *p = PATH(u);
+
+        assert(p);
+        assert(name);
+        assert(message);
+
+        if (u->transient && u->load_state == UNIT_STUB)
+                return bus_path_set_transient_property(p, name, message, mode, error);
+
+        return 0;
+}