1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "bus-label.h"
23 #include "bus-common-errors.h"
25 #include "machine-image.h"
26 #include "image-dbus.h"
28 static int image_find_by_bus_path(const char *path, Image **ret) {
29 _cleanup_free_ char *e = NULL;
34 p = startswith(path, "/org/freedesktop/machine1/image/");
38 e = bus_label_unescape(p);
42 return image_find(e, ret);
45 static int image_find_by_bus_path_with_error(const char *path, Image **ret, sd_bus_error *error) {
50 r = image_find_by_bus_path(path, ret);
52 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "Image doesn't exist.");
57 static int property_get_name(
60 const char *interface,
62 sd_bus_message *reply,
64 sd_bus_error *error) {
66 _cleanup_(image_unrefp) Image *image = NULL;
72 r = image_find_by_bus_path_with_error(path, &image, error);
76 r = sd_bus_message_append(reply, "s", image->name);
83 static int property_get_path(
86 const char *interface,
88 sd_bus_message *reply,
90 sd_bus_error *error) {
92 _cleanup_(image_unrefp) Image *image = NULL;
98 r = image_find_by_bus_path_with_error(path, &image, error);
102 r = sd_bus_message_append(reply, "s", image->path);
109 static int property_get_type(
112 const char *interface,
113 const char *property,
114 sd_bus_message *reply,
116 sd_bus_error *error) {
119 _cleanup_(image_unrefp) Image *image = NULL;
125 r = image_find_by_bus_path_with_error(path, &image, error);
129 r = sd_bus_message_append(reply, "s", image_type_to_string(image->type));
136 static int property_get_read_only(
139 const char *interface,
140 const char *property,
141 sd_bus_message *reply,
143 sd_bus_error *error) {
146 _cleanup_(image_unrefp) Image *image = NULL;
152 r = image_find_by_bus_path_with_error(path, &image, error);
156 r = sd_bus_message_append(reply, "b", image->read_only);
163 static int property_get_crtime(
166 const char *interface,
167 const char *property,
168 sd_bus_message *reply,
170 sd_bus_error *error) {
173 _cleanup_(image_unrefp) Image *image = NULL;
179 r = image_find_by_bus_path_with_error(path, &image, error);
183 r = sd_bus_message_append(reply, "t", image->crtime);
190 static int property_get_mtime(
193 const char *interface,
194 const char *property,
195 sd_bus_message *reply,
197 sd_bus_error *error) {
199 _cleanup_(image_unrefp) Image *image = NULL;
205 r = image_find_by_bus_path_with_error(path, &image, error);
209 r = sd_bus_message_append(reply, "t", image->mtime);
216 static int method_remove(
218 sd_bus_message *message,
220 sd_bus_error *error) {
222 _cleanup_(image_unrefp) Image *image = NULL;
228 r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
232 r = image_remove(image);
236 return sd_bus_reply_method_return(message, NULL);
239 static int method_rename(
241 sd_bus_message *message,
243 sd_bus_error *error) {
245 _cleanup_(image_unrefp) Image *image = NULL;
246 const char *new_name;
252 r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
256 r = sd_bus_message_read(message, "s", &new_name);
260 if (!image_name_is_valid(new_name))
261 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
263 r = image_rename(image, new_name);
267 return sd_bus_reply_method_return(message, NULL);
270 static int method_clone(
272 sd_bus_message *message,
274 sd_bus_error *error) {
276 _cleanup_(image_unrefp) Image *image = NULL;
277 const char *new_name;
283 r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
287 r = sd_bus_message_read(message, "sb", &new_name, &read_only);
291 if (!image_name_is_valid(new_name))
292 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
294 r = image_clone(image, new_name, read_only);
298 return sd_bus_reply_method_return(message, NULL);
301 static int method_mark_read_only(
303 sd_bus_message *message,
305 sd_bus_error *error) {
307 _cleanup_(image_unrefp) Image *image = NULL;
313 r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
317 r = sd_bus_message_read(message, "b", &read_only);
321 r = image_read_only(image, read_only);
325 return sd_bus_reply_method_return(message, NULL);
328 const sd_bus_vtable image_vtable[] = {
329 SD_BUS_VTABLE_START(0),
330 SD_BUS_PROPERTY("Name", "s", property_get_name, 0, 0),
331 SD_BUS_PROPERTY("Path", "s", property_get_path, 0, 0),
332 SD_BUS_PROPERTY("Type", "s", property_get_type, 0, 0),
333 SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0),
334 SD_BUS_PROPERTY("CreationTimestamp", "t", property_get_crtime, 0, 0),
335 SD_BUS_PROPERTY("ModificationTimestamp", "t", property_get_mtime, 0, 0),
336 SD_BUS_METHOD("Remove", NULL, NULL, method_remove, 0),
337 SD_BUS_METHOD("Rename", "s", NULL, method_rename, 0),
338 SD_BUS_METHOD("Clone", "sb", NULL, method_clone, 0),
339 SD_BUS_METHOD("MarkeReadOnly", "b", NULL, method_mark_read_only, 0),
343 int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
351 r = image_find_by_bus_path(path, NULL);
359 char *image_bus_path(const char *name) {
360 _cleanup_free_ char *e = NULL;
364 e = bus_label_escape(name);
368 return strappend("/org/freedesktop/machine1/image/", e);
371 int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
372 _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
373 _cleanup_strv_free_ char **l = NULL;
382 images = hashmap_new(&string_hash_ops);
386 r = image_discover(images);
390 HASHMAP_FOREACH(image, images, i) {
393 p = image_bus_path(image->name);
397 r = strv_consume(&l, p);