]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
01f78473 LP |
2 | /*** |
3 | This file is part of systemd. | |
4 | ||
5 | Copyright 2010 Lennart Poettering | |
01f78473 LP |
6 | ***/ |
7 | ||
5b9fbf89 | 8 | #include "alloc-util.h" |
07630cea | 9 | #include "bus-util.h" |
cf0fbc49 | 10 | #include "dbus-path.h" |
f76e92af | 11 | #include "dbus-util.h" |
5b9fbf89 | 12 | #include "list.h" |
718db961 | 13 | #include "path.h" |
5b9fbf89 | 14 | #include "path-util.h" |
07630cea LP |
15 | #include "string-util.h" |
16 | #include "unit.h" | |
718db961 LP |
17 | |
18 | static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, path_result, PathResult); | |
19 | ||
20 | static int property_get_paths( | |
21 | sd_bus *bus, | |
22 | const char *path, | |
23 | const char *interface, | |
24 | const char *property, | |
25 | sd_bus_message *reply, | |
ebcf1f97 LP |
26 | void *userdata, |
27 | sd_bus_error *error) { | |
718db961 LP |
28 | |
29 | Path *p = userdata; | |
ebf57b80 | 30 | PathSpec *k; |
718db961 | 31 | int r; |
ebf57b80 | 32 | |
718db961 LP |
33 | assert(bus); |
34 | assert(reply); | |
ebf57b80 LP |
35 | assert(p); |
36 | ||
718db961 LP |
37 | r = sd_bus_message_open_container(reply, 'a', "(ss)"); |
38 | if (r < 0) | |
39 | return r; | |
ebf57b80 LP |
40 | |
41 | LIST_FOREACH(spec, k, p->specs) { | |
718db961 LP |
42 | r = sd_bus_message_append(reply, "(ss)", path_type_to_string(k->type), k->path); |
43 | if (r < 0) | |
44 | return r; | |
ebf57b80 LP |
45 | } |
46 | ||
718db961 | 47 | return sd_bus_message_close_container(reply); |
ebf57b80 LP |
48 | } |
49 | ||
718db961 LP |
50 | const sd_bus_vtable bus_path_vtable[] = { |
51 | SD_BUS_VTABLE_START(0), | |
54138a8d | 52 | SD_BUS_PROPERTY("Unit", "s", bus_property_get_triggered_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST), |
556089dc LP |
53 | SD_BUS_PROPERTY("Paths", "a(ss)", property_get_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST), |
54 | SD_BUS_PROPERTY("MakeDirectory", "b", bus_property_get_bool, offsetof(Path, make_directory), SD_BUS_VTABLE_PROPERTY_CONST), | |
55 | SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Path, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST), | |
718db961 LP |
56 | SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Path, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), |
57 | SD_BUS_VTABLE_END | |
d200735e | 58 | }; |
5b9fbf89 YW |
59 | |
60 | static int bus_path_set_transient_property( | |
61 | Path *p, | |
62 | const char *name, | |
63 | sd_bus_message *message, | |
64 | UnitWriteFlags flags, | |
65 | sd_bus_error *error) { | |
66 | ||
67 | Unit *u = UNIT(p); | |
68 | int r; | |
69 | ||
70 | assert(p); | |
71 | assert(name); | |
72 | assert(message); | |
73 | ||
74 | flags |= UNIT_PRIVATE; | |
75 | ||
f76e92af YW |
76 | if (streq(name, "MakeDirectory")) |
77 | return bus_set_transient_bool(u, name, &p->make_directory, message, flags, error); | |
5b9fbf89 | 78 | |
f76e92af YW |
79 | if (streq(name, "DirectoryMode")) |
80 | return bus_set_transient_mode_t(u, name, &p->directory_mode, message, flags, error); | |
5b9fbf89 | 81 | |
f76e92af YW |
82 | if (streq(name, "Paths")) { |
83 | const char *type_name, *path; | |
84 | bool empty = true; | |
85 | ||
86 | r = sd_bus_message_enter_container(message, 'a', "(ss)"); | |
5b9fbf89 YW |
87 | if (r < 0) |
88 | return r; | |
89 | ||
f76e92af YW |
90 | while ((r = sd_bus_message_read(message, "(ss)", &type_name, &path)) > 0) { |
91 | PathType t; | |
92 | ||
93 | t = path_type_from_string(type_name); | |
94 | if (t < 0) | |
95 | return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown path type: %s", type_name); | |
96 | ||
97 | if (isempty(path)) | |
98 | return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is empty", type_name); | |
99 | ||
100 | if (!path_is_absolute(path)) | |
101 | return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is not absolute: %s", type_name, path); | |
5b9fbf89 | 102 | |
f76e92af | 103 | if (!UNIT_WRITE_FLAGS_NOOP(flags)) { |
5b9fbf89 YW |
104 | _cleanup_free_ char *k; |
105 | PathSpec *s; | |
106 | ||
f76e92af | 107 | k = strdup(path); |
5b9fbf89 YW |
108 | if (!k) |
109 | return -ENOMEM; | |
110 | ||
111 | s = new0(PathSpec, 1); | |
112 | if (!s) | |
113 | return -ENOMEM; | |
114 | ||
115 | s->unit = u; | |
116 | s->path = path_kill_slashes(k); | |
117 | k = NULL; | |
f76e92af | 118 | s->type = t; |
5b9fbf89 YW |
119 | s->inotify_fd = -1; |
120 | ||
121 | LIST_PREPEND(spec, p->specs, s); | |
122 | ||
f76e92af | 123 | unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", type_name, path); |
5b9fbf89 | 124 | } |
5b9fbf89 | 125 | |
f76e92af YW |
126 | empty = false; |
127 | } | |
5b9fbf89 YW |
128 | if (r < 0) |
129 | return r; | |
130 | ||
f76e92af | 131 | r = sd_bus_message_exit_container(message); |
5b9fbf89 YW |
132 | if (r < 0) |
133 | return r; | |
134 | ||
f76e92af YW |
135 | if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) { |
136 | path_free_specs(p); | |
137 | unit_write_settingf(u, flags, name, "PathExists="); | |
5b9fbf89 YW |
138 | } |
139 | ||
140 | return 1; | |
5b9fbf89 YW |
141 | } |
142 | ||
143 | return 0; | |
144 | } | |
145 | ||
146 | int bus_path_set_property( | |
147 | Unit *u, | |
148 | const char *name, | |
149 | sd_bus_message *message, | |
150 | UnitWriteFlags mode, | |
151 | sd_bus_error *error) { | |
152 | ||
153 | Path *p = PATH(u); | |
154 | ||
155 | assert(p); | |
156 | assert(name); | |
157 | assert(message); | |
158 | ||
159 | if (u->transient && u->load_state == UNIT_STUB) | |
160 | return bus_path_set_transient_property(p, name, message, mode, error); | |
161 | ||
162 | return 0; | |
163 | } |