chiark / gitweb /
afb849b41afb5d263bb3ca77a8b91f225c7e0e1e
[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 "image.h"
26
27 static int image_find_by_bus_path(const char *path, Image **ret) {
28         _cleanup_free_ char *e = NULL;
29         const char *p;
30
31         assert(path);
32
33         p = startswith(path, "/org/freedesktop/machine1/image/");
34         if (!p)
35                 return 0;
36
37         e = bus_label_unescape(p);
38         if (!e)
39                 return -ENOMEM;
40
41         return image_find(e, ret);
42 }
43
44 static int image_find_by_bus_path_with_error(const char *path, Image **ret, sd_bus_error *error) {
45         int r;
46
47         assert(path);
48
49         r = image_find_by_bus_path(path, ret);
50         if (r == 0)
51                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "Image doesn't exist.");
52
53         return r;
54 }
55
56 static int property_get_name(
57                 sd_bus *bus,
58                 const char *path,
59                 const char *interface,
60                 const char *property,
61                 sd_bus_message *reply,
62                 void *userdata,
63                 sd_bus_error *error) {
64
65         _cleanup_(image_unrefp) Image *image = NULL;
66         int r;
67
68         assert(bus);
69         assert(reply);
70
71         r = image_find_by_bus_path_with_error(path, &image, error);
72         if (r < 0)
73                 return r;
74
75         r = sd_bus_message_append(reply, "s", image->name);
76         if (r < 0)
77                 return r;
78
79         return 1;
80 }
81
82 static int property_get_path(
83                 sd_bus *bus,
84                 const char *path,
85                 const char *interface,
86                 const char *property,
87                 sd_bus_message *reply,
88                 void *userdata,
89                 sd_bus_error *error) {
90
91         _cleanup_(image_unrefp) Image *image = NULL;
92         int r;
93
94         assert(bus);
95         assert(reply);
96
97         r = image_find_by_bus_path_with_error(path, &image, error);
98         if (r < 0)
99                 return r;
100
101         r = sd_bus_message_append(reply, "s", image->path);
102         if (r < 0)
103                 return r;
104
105         return 1;
106 }
107
108 static int property_get_type(
109                 sd_bus *bus,
110                 const char *path,
111                 const char *interface,
112                 const char *property,
113                 sd_bus_message *reply,
114                 void *userdata,
115                 sd_bus_error *error) {
116
117
118         _cleanup_(image_unrefp) Image *image = NULL;
119         int r;
120
121         assert(bus);
122         assert(reply);
123
124         r = image_find_by_bus_path_with_error(path, &image, error);
125         if (r < 0)
126                 return r;
127
128         r = sd_bus_message_append(reply, "s", image_type_to_string(image->type));
129         if (r < 0)
130                 return r;
131
132         return 1;
133 }
134
135 static int property_get_read_only(
136                 sd_bus *bus,
137                 const char *path,
138                 const char *interface,
139                 const char *property,
140                 sd_bus_message *reply,
141                 void *userdata,
142                 sd_bus_error *error) {
143
144
145         _cleanup_(image_unrefp) Image *image = NULL;
146         int r;
147
148         assert(bus);
149         assert(reply);
150
151         r = image_find_by_bus_path_with_error(path, &image, error);
152         if (r < 0)
153                 return r;
154
155         r = sd_bus_message_append(reply, "b", image->read_only);
156         if (r < 0)
157                 return r;
158
159         return 1;
160 }
161
162 const sd_bus_vtable image_vtable[] = {
163         SD_BUS_VTABLE_START(0),
164         SD_BUS_PROPERTY("Name",     "s", property_get_name,      0, 0),
165         SD_BUS_PROPERTY("Path",     "s", property_get_path,      0, 0),
166         SD_BUS_PROPERTY("Type",     "s", property_get_type,      0, 0),
167         SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0),
168         SD_BUS_VTABLE_END
169 };
170
171 int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
172         int r;
173
174         assert(bus);
175         assert(path);
176         assert(interface);
177         assert(found);
178
179         r = image_find_by_bus_path(path, NULL);
180         if (r <= 0)
181                 return r;
182
183         *found = NULL;
184         return 1;
185 }
186
187 char *image_bus_path(const char *name) {
188         _cleanup_free_ char *e = NULL;
189
190         assert(name);
191
192         e = bus_label_escape(name);
193         if (!e)
194                 return NULL;
195
196         return strappend("/org/freedesktop/machine1/image/", e);
197 }
198
199 int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
200         _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
201         _cleanup_strv_free_ char **l = NULL;
202         Image *image;
203         Iterator i;
204         int r;
205
206         assert(bus);
207         assert(path);
208         assert(nodes);
209
210         images = hashmap_new(&string_hash_ops);
211         if (!images)
212                 return -ENOMEM;
213
214         r = image_discover(images);
215         if (r < 0)
216                 return r;
217
218         HASHMAP_FOREACH(image, images, i) {
219                 char *p;
220
221                 p = image_bus_path(image->name);
222                 if (!p)
223                         return -ENOMEM;
224
225                 r = strv_consume(&l, p);
226                 if (r < 0)
227                         return r;
228         }
229
230         *nodes = l;
231         l = NULL;
232
233         return 1;
234 }