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