chiark / gitweb /
bus: hook up client with socket communication
[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         char **x = NULL;
111         int r;
112
113         if (!bus)
114                 return -EINVAL;
115         if (!l)
116                 return -EINVAL;
117
118         r = sd_bus_message_new_method_call(
119                         bus,
120                         "org.freedesktop.DBus",
121                         "/",
122                         "org.freedesktop.DBus",
123                         "ListNames",
124                         &m1);
125         if (r < 0)
126                 return r;
127
128         r = sd_bus_message_new_method_call(
129                         bus,
130                         "org.freedesktop.DBus",
131                         "/",
132                         "org.freedesktop.DBus",
133                         "ListActivatableNames",
134                         &m2);
135         if (r < 0)
136                 return r;
137
138         r = sd_bus_send_with_reply_and_block(bus, m1, (uint64_t) -1, NULL, &reply1);
139         if (r < 0)
140                 return r;
141
142         r = sd_bus_send_with_reply_and_block(bus, m2, (uint64_t) -1, NULL, &reply2);
143         if (r < 0)
144                 return r;
145
146         r = bus_message_read_strv_extend(reply1, &x);
147         if (r < 0) {
148                 strv_free(x);
149                 return r;
150         }
151
152         r = bus_message_read_strv_extend(reply2, &x);
153         if (r < 0) {
154                 strv_free(x);
155                 return r;
156         }
157
158         *l = strv_uniq(x);
159         return 0;
160 }
161
162 int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) {
163         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
164         const char *found;
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         r = sd_bus_message_read(reply, "s", &found);
191         if (r < 0)
192                 return r;
193
194         if (owner) {
195                 char *t;
196
197                 t = strdup(found);
198                 if (!t)
199                         return -ENOMEM;
200
201                 *owner = t;
202         }
203
204         return 0;
205 }
206
207 int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) {
208         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
209         uint32_t u;
210         int r;
211
212         if (!bus)
213                 return -EINVAL;
214         if (!name)
215                 return -EINVAL;
216         if (!uid)
217                 return -EINVAL;
218
219         r = sd_bus_message_new_method_call(
220                         bus,
221                         "org.freedesktop.DBus",
222                         "/",
223                         "org.freedesktop.DBus",
224                         "GetConnectionUnixUser",
225                         &m);
226         if (r < 0)
227                 return r;
228
229         r = sd_bus_message_append(m, "s", name);
230         if (r < 0)
231                 return r;
232
233         r = sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
234         if (r < 0)
235                 return r;
236
237         r = sd_bus_message_read(reply, "u", &u);
238         if (r < 0)
239                 return r;
240
241         *uid = (uid_t) u;
242         return 0;
243 }
244
245 int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid) {
246         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
247         uint32_t u;
248         int r;
249
250         if (!bus)
251                 return -EINVAL;
252         if (!name)
253                 return -EINVAL;
254         if (!pid)
255                 return -EINVAL;
256
257         r = sd_bus_message_new_method_call(
258                         bus,
259                         "org.freedesktop.DBus",
260                         "/",
261                         "org.freedesktop.DBus",
262                         "GetConnectionUnixProcessID",
263                         &m);
264         if (r < 0)
265                 return r;
266
267         r = sd_bus_message_append(m, "s", name);
268         if (r < 0)
269                 return r;
270
271         r = sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
272         if (r < 0)
273                 return r;
274
275         r = sd_bus_message_read(reply, "u", &u);
276         if (r < 0)
277                 return r;
278
279         if (u == 0)
280                 return -EIO;
281
282         *pid = (uid_t) u;
283         return 0;
284 }
285
286 int sd_bus_add_match(sd_bus *bus, const char *match) {
287         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
288         int r;
289
290         if (!bus)
291                 return -EINVAL;
292         if (!match)
293                 return -EINVAL;
294
295         r = sd_bus_message_new_method_call(
296                         bus,
297                         "org.freedesktop.DBus",
298                         "/",
299                         "org.freedesktop.DBus",
300                         "AddMatch",
301                         &m);
302         if (r < 0)
303                 return r;
304
305         r = sd_bus_message_append(m, "s", match);
306         if (r < 0)
307                 return r;
308
309         return sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
310 }
311
312 int sd_bus_remove_match(sd_bus *bus, const char *match) {
313         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
314         int r;
315
316         if (!bus)
317                 return -EINVAL;
318         if (!match)
319                 return -EINVAL;
320
321         r = sd_bus_message_new_method_call(
322                         bus,
323                         "org.freedesktop.DBus",
324                         "/",
325                         "org.freedesktop.DBus",
326                         "RemoveMatch",
327                         &m);
328         if (r < 0)
329                 return r;
330
331         r = sd_bus_message_append(m, "s", match);
332         if (r < 0)
333                 return r;
334
335         return sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, NULL, &reply);
336 }