chiark / gitweb /
be2369953cb1d9d8ac60b5a6083efc8b02e3642a
[elogind.git] / src / machine / image-dbus.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2014 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include "bus-label.h"
23 #include "bus-common-errors.h"
24 #include "strv.h"
25 #include "machine-image.h"
26 #include "image-dbus.h"
27
28 static int image_find_by_bus_path(const char *path, Image **ret) {
29         _cleanup_free_ char *e = NULL;
30         const char *p;
31
32         assert(path);
33
34         p = startswith(path, "/org/freedesktop/machine1/image/");
35         if (!p)
36                 return 0;
37
38         e = bus_label_unescape(p);
39         if (!e)
40                 return -ENOMEM;
41
42         return image_find(e, ret);
43 }
44
45 static int image_find_by_bus_path_with_error(const char *path, Image **ret, sd_bus_error *error) {
46         int r;
47
48         assert(path);
49
50         r = image_find_by_bus_path(path, ret);
51         if (r == 0)
52                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "Image doesn't exist.");
53
54         return r;
55 }
56
57 static int property_get_name(
58                 sd_bus *bus,
59                 const char *path,
60                 const char *interface,
61                 const char *property,
62                 sd_bus_message *reply,
63                 void *userdata,
64                 sd_bus_error *error) {
65
66         _cleanup_(image_unrefp) Image *image = NULL;
67         int r;
68
69         assert(bus);
70         assert(reply);
71
72         r = image_find_by_bus_path_with_error(path, &image, error);
73         if (r < 0)
74                 return r;
75
76         r = sd_bus_message_append(reply, "s", image->name);
77         if (r < 0)
78                 return r;
79
80         return 1;
81 }
82
83 static int property_get_path(
84                 sd_bus *bus,
85                 const char *path,
86                 const char *interface,
87                 const char *property,
88                 sd_bus_message *reply,
89                 void *userdata,
90                 sd_bus_error *error) {
91
92         _cleanup_(image_unrefp) Image *image = NULL;
93         int r;
94
95         assert(bus);
96         assert(reply);
97
98         r = image_find_by_bus_path_with_error(path, &image, error);
99         if (r < 0)
100                 return r;
101
102         r = sd_bus_message_append(reply, "s", image->path);
103         if (r < 0)
104                 return r;
105
106         return 1;
107 }
108
109 static int property_get_type(
110                 sd_bus *bus,
111                 const char *path,
112                 const char *interface,
113                 const char *property,
114                 sd_bus_message *reply,
115                 void *userdata,
116                 sd_bus_error *error) {
117
118
119         _cleanup_(image_unrefp) Image *image = NULL;
120         int r;
121
122         assert(bus);
123         assert(reply);
124
125         r = image_find_by_bus_path_with_error(path, &image, error);
126         if (r < 0)
127                 return r;
128
129         r = sd_bus_message_append(reply, "s", image_type_to_string(image->type));
130         if (r < 0)
131                 return r;
132
133         return 1;
134 }
135
136 static int property_get_read_only(
137                 sd_bus *bus,
138                 const char *path,
139                 const char *interface,
140                 const char *property,
141                 sd_bus_message *reply,
142                 void *userdata,
143                 sd_bus_error *error) {
144
145
146         _cleanup_(image_unrefp) Image *image = NULL;
147         int r;
148
149         assert(bus);
150         assert(reply);
151
152         r = image_find_by_bus_path_with_error(path, &image, error);
153         if (r < 0)
154                 return r;
155
156         r = sd_bus_message_append(reply, "b", image->read_only);
157         if (r < 0)
158                 return r;
159
160         return 1;
161 }
162
163 static int property_get_crtime(
164                 sd_bus *bus,
165                 const char *path,
166                 const char *interface,
167                 const char *property,
168                 sd_bus_message *reply,
169                 void *userdata,
170                 sd_bus_error *error) {
171
172
173         _cleanup_(image_unrefp) Image *image = NULL;
174         int r;
175
176         assert(bus);
177         assert(reply);
178
179         r = image_find_by_bus_path_with_error(path, &image, error);
180         if (r < 0)
181                 return r;
182
183         r = sd_bus_message_append(reply, "t", image->crtime);
184         if (r < 0)
185                 return r;
186
187         return 1;
188 }
189
190 static int property_get_mtime(
191                 sd_bus *bus,
192                 const char *path,
193                 const char *interface,
194                 const char *property,
195                 sd_bus_message *reply,
196                 void *userdata,
197                 sd_bus_error *error) {
198
199         _cleanup_(image_unrefp) Image *image = NULL;
200         int r;
201
202         assert(bus);
203         assert(reply);
204
205         r = image_find_by_bus_path_with_error(path, &image, error);
206         if (r < 0)
207                 return r;
208
209         r = sd_bus_message_append(reply, "t", image->mtime);
210         if (r < 0)
211                 return r;
212
213         return 1;
214 }
215
216 static int method_remove(
217                 sd_bus *bus,
218                 sd_bus_message *message,
219                 void *userdata,
220                 sd_bus_error *error) {
221
222         _cleanup_(image_unrefp) Image *image = NULL;
223         int r;
224
225         assert(bus);
226         assert(message);
227
228         r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
229         if (r < 0)
230                 return r;
231
232         r = image_remove(image);
233         if (r < 0)
234                 return r;
235
236         return sd_bus_reply_method_return(message, NULL);
237 }
238
239 const sd_bus_vtable image_vtable[] = {
240         SD_BUS_VTABLE_START(0),
241         SD_BUS_PROPERTY("Name",                  "s", property_get_name,      0, 0),
242         SD_BUS_PROPERTY("Path",                  "s", property_get_path,      0, 0),
243         SD_BUS_PROPERTY("Type",                  "s", property_get_type,      0, 0),
244         SD_BUS_PROPERTY("ReadOnly",              "b", property_get_read_only, 0, 0),
245         SD_BUS_PROPERTY("CreationTimestamp",     "t", property_get_crtime,    0, 0),
246         SD_BUS_PROPERTY("ModificationTimestamp", "t", property_get_mtime,     0, 0),
247         SD_BUS_METHOD("Remove", NULL, NULL, method_remove, 0),
248         SD_BUS_VTABLE_END
249 };
250
251 int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
252         int r;
253
254         assert(bus);
255         assert(path);
256         assert(interface);
257         assert(found);
258
259         r = image_find_by_bus_path(path, NULL);
260         if (r <= 0)
261                 return r;
262
263         *found = NULL;
264         return 1;
265 }
266
267 char *image_bus_path(const char *name) {
268         _cleanup_free_ char *e = NULL;
269
270         assert(name);
271
272         e = bus_label_escape(name);
273         if (!e)
274                 return NULL;
275
276         return strappend("/org/freedesktop/machine1/image/", e);
277 }
278
279 int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
280         _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
281         _cleanup_strv_free_ char **l = NULL;
282         Image *image;
283         Iterator i;
284         int r;
285
286         assert(bus);
287         assert(path);
288         assert(nodes);
289
290         images = hashmap_new(&string_hash_ops);
291         if (!images)
292                 return -ENOMEM;
293
294         r = image_discover(images);
295         if (r < 0)
296                 return r;
297
298         HASHMAP_FOREACH(image, images, i) {
299                 char *p;
300
301                 p = image_bus_path(image->name);
302                 if (!p)
303                         return -ENOMEM;
304
305                 r = strv_consume(&l, p);
306                 if (r < 0)
307                         return r;
308         }
309
310         *nodes = l;
311         l = NULL;
312
313         return 1;
314 }