chiark / gitweb /
e4cc251a4b2937046fc159d6a6f7c089e4be3c54
[elogind.git] / src / libsystemd-bus / bus-control.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 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 <stddef.h>
23 #include <errno.h>
24
25 #include "strv.h"
26
27 #include "sd-bus.h"
28 #include "bus-internal.h"
29 #include "bus-message.h"
30
31 const char *sd_bus_get_unique_name(sd_bus *bus) {
32         if (!bus)
33                 return NULL;
34
35         return bus->unique_name;
36 }
37
38 int sd_bus_request_name(sd_bus *bus, const char *name, int flags) {
39         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
40         uint32_t ret;
41         int r;
42
43         if (!bus)
44                 return -EINVAL;
45         if (!name)
46                 return -EINVAL;
47
48         r = sd_bus_message_new_method_call(
49                         bus,
50                         "org.freedesktop.DBus",
51                         "/",
52                         "org.freedesktop.DBus",
53                         "RequestName",
54                         &m);
55         if (r < 0)
56                 return r;
57
58         r = sd_bus_message_append(m, "su", name, flags);
59         if (r < 0)
60                 return r;
61
62         r = sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
63         if (r < 0)
64                 return r;
65
66         r = sd_bus_message_read(reply, "u", &ret);
67         if (r < 0)
68                 return r;
69
70         return ret;
71 }
72
73 int sd_bus_release_name(sd_bus *bus, const char *name) {
74         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
75         uint32_t ret;
76         int r;
77
78         if (!bus)
79                 return -EINVAL;
80         if (!name)
81                 return -EINVAL;
82
83         r = sd_bus_message_new_method_call(
84                         bus,
85                         "org.freedesktop.DBus",
86                         "/",
87                         "org.freedesktop.DBus",
88                         "ReleaseName",
89                         &m);
90         if (r < 0)
91                 return r;
92
93         r = sd_bus_message_append(m, "s", name);
94         if (r < 0)
95                 return r;
96
97         r = sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
98         if (r < 0)
99                 return r;
100
101         r = sd_bus_message_read(reply, "u", &ret);
102         if (r < 0)
103                 return r;
104
105         return ret;
106 }
107
108 int sd_bus_list_names(sd_bus *bus, char ***l) {
109         _cleanup_bus_message_unref_ sd_bus_message *m1 = NULL, *reply1 = NULL, *m2 = NULL, *reply2 = NULL;
110         _cleanup_strv_free_ char **a = NULL, **b = NULL;
111         char **x = NULL;
112         int r;
113
114         if (!bus)
115                 return -EINVAL;
116         if (!l)
117                 return -EINVAL;
118
119         r = sd_bus_message_new_method_call(
120                         bus,
121                         "org.freedesktop.DBus",
122                         "/",
123                         "org.freedesktop.DBus",
124                         "ListNames",
125                         &m1);
126         if (r < 0)
127                 return r;
128
129         r = sd_bus_message_new_method_call(
130                         bus,
131                         "org.freedesktop.DBus",
132                         "/",
133                         "org.freedesktop.DBus",
134                         "ListActivatableNames",
135                         &m2);
136         if (r < 0)
137                 return r;
138
139         r = sd_bus_send_with_reply_and_block(bus, m1, (uint64_t) -1, NULL, &reply1);
140         if (r < 0)
141                 return r;
142
143         r = sd_bus_send_with_reply_and_block(bus, m2, (uint64_t) -1, NULL, &reply2);
144         if (r < 0)
145                 return r;
146
147         r = sd_bus_message_read(reply1, "as", &a);
148         if (r < 0)
149                 return r;
150
151         r = sd_bus_message_read(reply2, "as", &b);
152         if (r < 0)
153                 return r;
154
155         x = strv_merge(a, b);
156         if (!x)
157                 return -ENOMEM;
158
159         *l = strv_uniq(x);
160         return 0;
161 }
162
163 int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) {
164         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
165         int r;
166
167         if (!bus)
168                 return -EINVAL;
169         if (!name)
170                 return -EINVAL;
171
172         r = sd_bus_message_new_method_call(
173                         bus,
174                         "org.freedesktop.DBus",
175                         "/",
176                         "org.freedesktop.DBus",
177                         "GetNameOwner",
178                         &m);
179         if (r < 0)
180                 return r;
181
182         r = sd_bus_message_append(m, "s", name);
183         if (r < 0)
184                 return r;
185
186         r = sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
187         if (r < 0)
188                 return r;
189
190         return sd_bus_message_read(reply, "s", owner);
191 }
192
193 int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) {
194         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
195         uint32_t u;
196         int r;
197
198         if (!bus)
199                 return -EINVAL;
200         if (!name)
201                 return -EINVAL;
202         if (!uid)
203                 return -EINVAL;
204
205         r = sd_bus_message_new_method_call(
206                         bus,
207                         "org.freedesktop.DBus",
208                         "/",
209                         "org.freedesktop.DBus",
210                         "GetConnectionUnixUser",
211                         &m);
212         if (r < 0)
213                 return r;
214
215         r = sd_bus_message_append(m, "s", name);
216         if (r < 0)
217                 return r;
218
219         r = sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
220         if (r < 0)
221                 return r;
222
223         r = sd_bus_message_read(reply, "u", &u);
224         if (r < 0)
225                 return r;
226
227         *uid = (uid_t) u;
228         return 0;
229 }
230
231 int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid) {
232         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
233         uint32_t u;
234         int r;
235
236         if (!bus)
237                 return -EINVAL;
238         if (!name)
239                 return -EINVAL;
240         if (!pid)
241                 return -EINVAL;
242
243         r = sd_bus_message_new_method_call(
244                         bus,
245                         "org.freedesktop.DBus",
246                         "/",
247                         "org.freedesktop.DBus",
248                         "GetConnectionUnixUser",
249                         &m);
250         if (r < 0)
251                 return r;
252
253         r = sd_bus_message_append(m, "s", name);
254         if (r < 0)
255                 return r;
256
257         r = sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
258         if (r < 0)
259                 return r;
260
261         r = sd_bus_message_read(reply, "u", &u);
262         if (r < 0)
263                 return r;
264
265         if (u == 0)
266                 return -EIO;
267
268         *pid = (uid_t) u;
269         return 0;
270 }
271
272 int sd_bus_add_match(sd_bus *bus, const char *match) {
273         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
274         int r;
275
276         if (!bus)
277                 return -EINVAL;
278         if (!match)
279                 return -EINVAL;
280
281         r = sd_bus_message_new_method_call(
282                         bus,
283                         "org.freedesktop.DBus",
284                         "/",
285                         "org.freedesktop.DBus",
286                         "AddMatch",
287                         &m);
288         if (r < 0)
289                 return r;
290
291         r = sd_bus_message_append(m, "s", match);
292         if (r < 0)
293                 return r;
294
295         return sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
296 }
297
298 int sd_bus_remove_match(sd_bus *bus, const char *match) {
299         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
300         int r;
301
302         if (!bus)
303                 return -EINVAL;
304         if (!match)
305                 return -EINVAL;
306
307         r = sd_bus_message_new_method_call(
308                         bus,
309                         "org.freedesktop.DBus",
310                         "/",
311                         "org.freedesktop.DBus",
312                         "RemoveMatch",
313                         &m);
314         if (r < 0)
315                 return r;
316
317         r = sd_bus_message_append(m, "s", match);
318         if (r < 0)
319                 return r;
320
321         return sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
322 }