]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/sd-bus.c
log: minimize includes in log.h
[thirdparty/systemd.git] / src / libsystemd / sd-bus / sd-bus.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
de1c301e
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2013 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
21#include <endian.h>
de1c301e 22#include <netdb.h>
0a6f50c0 23#include <poll.h>
45fbe937 24#include <pthread.h>
cf0fbc49
TA
25#include <stdlib.h>
26#include <sys/mman.h>
27#include <unistd.h>
de1c301e 28
de1c301e 29#include "sd-bus.h"
07630cea 30
b5efdb8a 31#include "alloc-util.h"
07630cea
LP
32#include "bus-container.h"
33#include "bus-control.h"
de1c301e 34#include "bus-internal.h"
6629161f 35#include "bus-kernel.h"
07630cea
LP
36#include "bus-label.h"
37#include "bus-message.h"
992c052c 38#include "bus-objects.h"
0461f8cd 39#include "bus-protocol.h"
19befb2d 40#include "bus-slot.h"
07630cea
LP
41#include "bus-socket.h"
42#include "bus-track.h"
43#include "bus-type.h"
44#include "bus-util.h"
45#include "cgroup-util.h"
46#include "def.h"
3ffd4af2 47#include "fd-util.h"
cf0fbc49 48#include "hexdecoct.h"
07630cea
LP
49#include "hostname-util.h"
50#include "macro.h"
51#include "missing.h"
6bedfcbb 52#include "parse-util.h"
dccca82b 53#include "process-util.h"
07630cea
LP
54#include "string-util.h"
55#include "strv.h"
56#include "util.h"
de1c301e 57
b56c4604
LP
58#define log_debug_bus_message(m) \
59 do { \
60 sd_bus_message *_mm = (m); \
e32fd6b4 61 log_debug("Got message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s", \
b56c4604
LP
62 bus_message_type_to_string(_mm->header->type), \
63 strna(sd_bus_message_get_sender(_mm)), \
64 strna(sd_bus_message_get_destination(_mm)), \
65 strna(sd_bus_message_get_path(_mm)), \
66 strna(sd_bus_message_get_interface(_mm)), \
67 strna(sd_bus_message_get_member(_mm)), \
68 BUS_MESSAGE_COOKIE(_mm), \
69 _mm->reply_cookie, \
e32fd6b4 70 strna(_mm->root_container.signature), \
e28d0865 71 strna(_mm->error.name), \
b56c4604
LP
72 strna(_mm->error.message)); \
73 } while (false)
f9f97ca6 74
e3017af9 75static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
8a5cd31e
LP
76static void bus_detach_io_events(sd_bus *b);
77static void bus_detach_inotify_event(sd_bus *b);
e3017af9 78
fa2f8973
LP
79static thread_local sd_bus *default_system_bus = NULL;
80static thread_local sd_bus *default_user_bus = NULL;
81static thread_local sd_bus *default_starter_bus = NULL;
82
8a5cd31e 83void bus_close_io_fds(sd_bus *b) {
f54514f3
LP
84 assert(b);
85
8a5cd31e 86 bus_detach_io_events(b);
1e05d493 87
0fd8d506 88 if (b->input_fd != b->output_fd)
03e334a1 89 safe_close(b->output_fd);
0fd8d506 90 b->output_fd = b->input_fd = safe_close(b->input_fd);
f54514f3
LP
91}
92
8a5cd31e
LP
93void bus_close_inotify_fd(sd_bus *b) {
94 assert(b);
95
96 bus_detach_inotify_event(b);
97
98 b->inotify_fd = safe_close(b->inotify_fd);
99 b->inotify_watches = mfree(b->inotify_watches);
100 b->n_inotify_watches = 0;
101}
102
0e586eae 103static void bus_reset_queues(sd_bus *b) {
0e586eae
LP
104 assert(b);
105
f389bf15
LP
106 while (b->rqueue_size > 0)
107 sd_bus_message_unref(b->rqueue[--b->rqueue_size]);
108
253f96e5 109 b->rqueue = mfree(b->rqueue);
f389bf15 110 b->rqueue_allocated = 0;
0e586eae 111
f389bf15
LP
112 while (b->wqueue_size > 0)
113 sd_bus_message_unref(b->wqueue[--b->wqueue_size]);
0e586eae 114
253f96e5 115 b->wqueue = mfree(b->wqueue);
f389bf15 116 b->wqueue_allocated = 0;
0e586eae
LP
117}
118
de1c301e 119static void bus_free(sd_bus *b) {
19befb2d 120 sd_bus_slot *s;
de1c301e
LP
121
122 assert(b);
8f8f05a9 123 assert(!b->track_queue);
232f3677 124 assert(!b->tracks);
8f8f05a9 125
19befb2d
LP
126 b->state = BUS_CLOSED;
127
40ca29a1
LP
128 sd_bus_detach_event(b);
129
19befb2d
LP
130 while ((s = b->slots)) {
131 /* At this point only floating slots can still be
132 * around, because the non-floating ones keep a
133 * reference to the bus, and we thus couldn't be
134 * destructing right now... We forcibly disconnect the
135 * slots here, so that they still can be referenced by
136 * apps, but are dead. */
137
138 assert(s->floating);
139 bus_slot_disconnect(s);
140 sd_bus_slot_unref(s);
141 }
142
f4d140e9
LP
143 if (b->default_bus_ptr)
144 *b->default_bus_ptr = NULL;
145
8a5cd31e
LP
146 bus_close_io_fds(b);
147 bus_close_inotify_fd(b);
de1c301e 148
c4e6556c 149 free(b->label);
18ac4643 150 free(b->groups);
de1c301e 151 free(b->rbuffer);
89ffcd2a 152 free(b->unique_name);
2181a7f5 153 free(b->auth_buffer);
89ffcd2a 154 free(b->address);
a7893c6b 155 free(b->machine);
751bc6ac 156 free(b->cgroup_root);
455971c1 157 free(b->description);
48ef41a3 158 free(b->patch_sender);
89ffcd2a 159
2fd9ae2e
LP
160 free(b->exec_path);
161 strv_free(b->exec_argv);
162
2c93b4ef
LP
163 close_many(b->fds, b->n_fds);
164 free(b->fds);
165
0e586eae 166 bus_reset_queues(b);
de1c301e 167
c9fe4af7 168 ordered_hashmap_free_free(b->reply_callbacks);
e3017af9 169 prioq_free(b->reply_callbacks_prioq);
de1c301e 170
75a0da95 171 assert(b->match_callbacks.type == BUS_MATCH_ROOT);
392d5b37
LP
172 bus_match_free(&b->match_callbacks);
173
29ddb38f
LP
174 hashmap_free_free(b->vtable_methods);
175 hashmap_free_free(b->vtable_properties);
176
19befb2d 177 assert(hashmap_isempty(b->nodes));
29ddb38f
LP
178 hashmap_free(b->nodes);
179
a132bef0 180 bus_flush_memfd(b);
bc7fd8cd 181
45fbe937
LP
182 assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
183
de1c301e
LP
184 free(b);
185}
186
d9f644e2 187_public_ int sd_bus_new(sd_bus **ret) {
de1c301e
LP
188 sd_bus *r;
189
d6888822 190 assert_return(ret, -EINVAL);
021a1e78 191
de1c301e
LP
192 r = new0(sd_bus, 1);
193 if (!r)
021a1e78 194 return -ENOMEM;
de1c301e 195
e4ee6e5c 196 r->n_ref = REFCNT_INIT;
e82c9509 197 r->input_fd = r->output_fd = -1;
8a5cd31e 198 r->inotify_fd = -1;
de1c301e 199 r->message_version = 1;
3310dfd5 200 r->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
c7db1984 201 r->accept_fd = true;
df0ff127 202 r->original_pid = getpid_cached();
18ac4643 203 r->n_groups = (size_t) -1;
de1c301e 204
45fbe937
LP
205 assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
206
de1c301e
LP
207 /* We guarantee that wqueue always has space for at least one
208 * entry */
821e0756 209 if (!GREEDY_REALLOC(r->wqueue, r->wqueue_allocated, 1)) {
de1c301e 210 free(r);
021a1e78 211 return -ENOMEM;
de1c301e
LP
212 }
213
021a1e78
LP
214 *ret = r;
215 return 0;
216}
217
d9f644e2 218_public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
021a1e78
LP
219 char *a;
220
d6888822
LP
221 assert_return(bus, -EINVAL);
222 assert_return(bus->state == BUS_UNSET, -EPERM);
223 assert_return(address, -EINVAL);
224 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
225
226 a = strdup(address);
227 if (!a)
228 return -ENOMEM;
229
230 free(bus->address);
231 bus->address = a;
232
233 return 0;
234}
235
d9f644e2 236_public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
d6888822
LP
237 assert_return(bus, -EINVAL);
238 assert_return(bus->state == BUS_UNSET, -EPERM);
8ac43fee
LP
239 assert_return(input_fd >= 0, -EBADF);
240 assert_return(output_fd >= 0, -EBADF);
d6888822 241 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 242
e82c9509
LP
243 bus->input_fd = input_fd;
244 bus->output_fd = output_fd;
021a1e78
LP
245 return 0;
246}
247
d9f644e2 248_public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
2fd9ae2e
LP
249 char *p, **a;
250
d6888822
LP
251 assert_return(bus, -EINVAL);
252 assert_return(bus->state == BUS_UNSET, -EPERM);
253 assert_return(path, -EINVAL);
254 assert_return(!strv_isempty(argv), -EINVAL);
255 assert_return(!bus_pid_changed(bus), -ECHILD);
2fd9ae2e
LP
256
257 p = strdup(path);
258 if (!p)
259 return -ENOMEM;
260
261 a = strv_copy(argv);
262 if (!a) {
263 free(p);
264 return -ENOMEM;
265 }
266
267 free(bus->exec_path);
268 strv_free(bus->exec_argv);
269
270 bus->exec_path = p;
271 bus->exec_argv = a;
272
273 return 0;
274}
275
d9f644e2 276_public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
d6888822
LP
277 assert_return(bus, -EINVAL);
278 assert_return(bus->state == BUS_UNSET, -EPERM);
48ef41a3 279 assert_return(!bus->patch_sender, -EPERM);
d6888822 280 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 281
94bbf1ba 282 bus->bus_client = !!b;
021a1e78
LP
283 return 0;
284}
285
09365592
LP
286_public_ int sd_bus_set_monitor(sd_bus *bus, int b) {
287 assert_return(bus, -EINVAL);
288 assert_return(bus->state == BUS_UNSET, -EPERM);
289 assert_return(!bus_pid_changed(bus), -ECHILD);
290
c7db1984 291 bus->is_monitor = b;
09365592
LP
292 return 0;
293}
294
d9f644e2 295_public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
d6888822
LP
296 assert_return(bus, -EINVAL);
297 assert_return(bus->state == BUS_UNSET, -EPERM);
298 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 299
c7db1984 300 bus->accept_fd = b;
264ad849
LP
301 return 0;
302}
303
4fc31988 304_public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) {
16be4368 305 assert_return(bus, -EINVAL);
b5dae4c7 306 assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
16be4368
KS
307 assert_return(!bus_pid_changed(bus), -ECHILD);
308
c7db1984
LP
309 /* This is not actually supported by any of our transports these days, but we do honour it for synthetic
310 * replies, and maybe one day classic D-Bus learns this too */
311 bus->attach_timestamp = b;
b5dae4c7 312
16be4368
KS
313 return 0;
314}
315
b5dae4c7 316_public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) {
16be4368 317 assert_return(bus, -EINVAL);
95c4fe82 318 assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL);
b5dae4c7 319 assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
16be4368
KS
320 assert_return(!bus_pid_changed(bus), -ECHILD);
321
5883ff60 322 SET_FLAG(bus->creds_mask, mask, b);
b5dae4c7 323
49b832c5 324 /* The well knowns we need unconditionally, so that matches can work */
b5dae4c7
LP
325 bus->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
326
b5dae4c7 327 return 0;
021a1e78 328}
de1c301e 329
d9f644e2 330_public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
d6888822
LP
331 assert_return(bus, -EINVAL);
332 assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL);
333 assert_return(bus->state == BUS_UNSET, -EPERM);
334 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
335
336 bus->is_server = !!b;
98178d39 337 bus->server_id = server_id;
2181a7f5
LP
338 return 0;
339}
340
d9f644e2 341_public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
d6888822
LP
342 assert_return(bus, -EINVAL);
343 assert_return(bus->state == BUS_UNSET, -EPERM);
344 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
345
346 bus->anonymous_auth = !!b;
347 return 0;
348}
349
adacb957
LP
350_public_ int sd_bus_set_trusted(sd_bus *bus, int b) {
351 assert_return(bus, -EINVAL);
352 assert_return(bus->state == BUS_UNSET, -EPERM);
353 assert_return(!bus_pid_changed(bus), -ECHILD);
354
355 bus->trusted = !!b;
356 return 0;
357}
358
455971c1 359_public_ int sd_bus_set_description(sd_bus *bus, const char *description) {
5972fe95 360 assert_return(bus, -EINVAL);
5972fe95
LP
361 assert_return(bus->state == BUS_UNSET, -EPERM);
362 assert_return(!bus_pid_changed(bus), -ECHILD);
363
d1b91c99 364 return free_and_strdup(&bus->description, description);
5972fe95
LP
365}
366
c0765ddb
LP
367_public_ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b) {
368 assert_return(bus, -EINVAL);
369 assert_return(!bus_pid_changed(bus), -ECHILD);
370
371 bus->allow_interactive_authorization = !!b;
372 return 0;
373}
374
375_public_ int sd_bus_get_allow_interactive_authorization(sd_bus *bus) {
376 assert_return(bus, -EINVAL);
377 assert_return(!bus_pid_changed(bus), -ECHILD);
378
379 return bus->allow_interactive_authorization;
380}
381
8a5cd31e
LP
382_public_ int sd_bus_set_watch_bind(sd_bus *bus, int b) {
383 assert_return(bus, -EINVAL);
384 assert_return(bus->state == BUS_UNSET, -EPERM);
385 assert_return(!bus_pid_changed(bus), -ECHILD);
386
387 bus->watch_bind = b;
388 return 0;
389}
390
391_public_ int sd_bus_get_watch_bind(sd_bus *bus) {
392 assert_return(bus, -EINVAL);
393 assert_return(!bus_pid_changed(bus), -ECHILD);
394
395 return bus->watch_bind;
396}
397
b38cc8d5
LP
398_public_ int sd_bus_set_connected_signal(sd_bus *bus, int b) {
399 assert_return(bus, -EINVAL);
400 assert_return(bus->state == BUS_UNSET, -EPERM);
401 assert_return(!bus_pid_changed(bus), -ECHILD);
402
403 bus->connected_signal = b;
404 return 0;
405}
406
407_public_ int sd_bus_get_connected_signal(sd_bus *bus) {
408 assert_return(bus, -EINVAL);
409 assert_return(!bus_pid_changed(bus), -ECHILD);
410
411 return bus->connected_signal;
412}
413
414static int synthesize_connected_signal(sd_bus *bus) {
415 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
416 int r;
417
418 assert(bus);
419
420 /* If enabled, synthesizes a local "Connected" signal mirroring the local "Disconnected" signal. This is called
421 * whenever we fully established a connection, i.e. after the authorization phase, and after receiving the
422 * Hello() reply. Or in other words, whenver we enter BUS_RUNNING state.
423 *
424 * This is useful so that clients can start doing stuff whenver the connection is fully established in a way
425 * that works independently from whether we connected to a full bus or just a direct connection. */
426
427 if (!bus->connected_signal)
428 return 0;
429
430 r = sd_bus_message_new_signal(
431 bus,
432 &m,
433 "/org/freedesktop/DBus/Local",
434 "org.freedesktop.DBus.Local",
435 "Connected");
436 if (r < 0)
437 return r;
438
439 bus_message_set_sender_local(bus, m);
440
441 r = bus_seal_synthetic_message(bus, m);
442 if (r < 0)
443 return r;
444
445 r = bus_rqueue_make_room(bus);
446 if (r < 0)
447 return r;
448
449 /* Insert at the very front */
450 memmove(bus->rqueue + 1, bus->rqueue, sizeof(sd_bus_message*) * bus->rqueue_size);
451 bus->rqueue[0] = m;
452 m = NULL;
453 bus->rqueue_size++;
454
455 return 0;
456}
457
3e0e196e
LP
458void bus_set_state(sd_bus *bus, enum bus_state state) {
459
460 static const char * const table[_BUS_STATE_MAX] = {
461 [BUS_UNSET] = "UNSET",
462 [BUS_WATCH_BIND] = "WATCH_BIND",
463 [BUS_OPENING] = "OPENING",
464 [BUS_AUTHENTICATING] = "AUTHENTICATING",
465 [BUS_HELLO] = "HELLO",
466 [BUS_RUNNING] = "RUNNING",
467 [BUS_CLOSING] = "CLOSING",
468 [BUS_CLOSED] = "CLOSED",
469 };
470
471 assert(bus);
472 assert(state < _BUS_STATE_MAX);
473
474 if (state == bus->state)
475 return;
476
477 log_debug("Bus %s: changing state %s → %s", strna(bus->description), table[bus->state], table[state]);
478 bus->state = state;
479}
480
19070062 481static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
de1c301e 482 const char *s;
19070062 483 sd_bus *bus;
de1c301e
LP
484 int r;
485
19070062
LP
486 assert(reply);
487 bus = reply->bus;
de1c301e 488 assert(bus);
945c2931 489 assert(IN_SET(bus->state, BUS_HELLO, BUS_CLOSING));
de1c301e 490
40ca29a1 491 r = sd_bus_message_get_errno(reply);
40ca29a1
LP
492 if (r > 0)
493 return -r;
eb01ba5d 494
de1c301e
LP
495 r = sd_bus_message_read(reply, "s", &s);
496 if (r < 0)
497 return r;
498
dafb7591
LP
499 if (!service_name_is_valid(s) || s[0] != ':')
500 return -EBADMSG;
501
de1c301e
LP
502 bus->unique_name = strdup(s);
503 if (!bus->unique_name)
504 return -ENOMEM;
505
b38cc8d5 506 if (bus->state == BUS_HELLO) {
3e0e196e 507 bus_set_state(bus, BUS_RUNNING);
dafb7591 508
b38cc8d5
LP
509 r = synthesize_connected_signal(bus);
510 if (r < 0)
511 return r;
512 }
513
de1c301e
LP
514 return 1;
515}
516
517static int bus_send_hello(sd_bus *bus) {
4afd3348 518 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
de1c301e
LP
519 int r;
520
521 assert(bus);
522
a132bef0 523 if (!bus->bus_client)
021a1e78
LP
524 return 0;
525
de1c301e
LP
526 r = sd_bus_message_new_method_call(
527 bus,
151b9b96 528 &m,
de1c301e 529 "org.freedesktop.DBus",
a7639e37 530 "/org/freedesktop/DBus",
de1c301e 531 "org.freedesktop.DBus",
151b9b96 532 "Hello");
de1c301e
LP
533 if (r < 0)
534 return r;
535
19befb2d 536 return sd_bus_call_async(bus, NULL, m, hello_callback, NULL, 0);
de1c301e
LP
537}
538
a7e3212d 539int bus_start_running(sd_bus *bus) {
ac8029fc
LP
540 struct reply_callback *c;
541 Iterator i;
542 usec_t n;
b38cc8d5 543 int r;
ac8029fc 544
de1c301e 545 assert(bus);
ac8029fc
LP
546 assert(bus->state < BUS_HELLO);
547
548 /* We start all method call timeouts when we enter BUS_HELLO or BUS_RUNNING mode. At this point let's convert
549 * all relative to absolute timestamps. Note that we do not reshuffle the reply callback priority queue since
550 * adding a fixed value to all entries should not alter the internal order. */
551
552 n = now(CLOCK_MONOTONIC);
553 ORDERED_HASHMAP_FOREACH(c, bus->reply_callbacks, i) {
554 if (c->timeout_usec == 0)
555 continue;
556
557 c->timeout_usec = usec_add(n, c->timeout_usec);
558 }
de1c301e 559
a132bef0 560 if (bus->bus_client) {
3e0e196e 561 bus_set_state(bus, BUS_HELLO);
e3017af9 562 return 1;
de1c301e
LP
563 }
564
3e0e196e 565 bus_set_state(bus, BUS_RUNNING);
b38cc8d5
LP
566
567 r = synthesize_connected_signal(bus);
568 if (r < 0)
569 return r;
570
e3017af9 571 return 1;
de1c301e
LP
572}
573
574static int parse_address_key(const char **p, const char *key, char **value) {
821e0756 575 size_t l, n = 0, allocated = 0;
de1c301e
LP
576 const char *a;
577 char *r = NULL;
578
579 assert(p);
580 assert(*p);
de1c301e
LP
581 assert(value);
582
2fd9ae2e
LP
583 if (key) {
584 l = strlen(key);
585 if (strncmp(*p, key, l) != 0)
586 return 0;
de1c301e 587
2fd9ae2e
LP
588 if ((*p)[l] != '=')
589 return 0;
de1c301e 590
2fd9ae2e
LP
591 if (*value)
592 return -EINVAL;
de1c301e 593
2fd9ae2e
LP
594 a = *p + l + 1;
595 } else
596 a = *p;
597
945c2931 598 while (!IN_SET(*a, ';', ',', 0)) {
821e0756 599 char c;
de1c301e
LP
600
601 if (*a == '%') {
602 int x, y;
603
604 x = unhexchar(a[1]);
605 if (x < 0) {
606 free(r);
607 return x;
608 }
609
610 y = unhexchar(a[2]);
611 if (y < 0) {
612 free(r);
613 return y;
614 }
615
de1c301e 616 c = (char) ((x << 4) | y);
89ffcd2a
LP
617 a += 3;
618 } else {
de1c301e 619 c = *a;
89ffcd2a
LP
620 a++;
621 }
de1c301e 622
821e0756 623 if (!GREEDY_REALLOC(r, allocated, n + 2))
de1c301e 624 return -ENOMEM;
de1c301e 625
de1c301e
LP
626 r[n++] = c;
627 }
628
89ffcd2a
LP
629 if (!r) {
630 r = strdup("");
631 if (!r)
632 return -ENOMEM;
633 } else
634 r[n] = 0;
635
636 if (*a == ',')
637 a++;
638
de1c301e 639 *p = a;
2fd9ae2e
LP
640
641 free(*value);
de1c301e 642 *value = r;
2fd9ae2e 643
de1c301e
LP
644 return 1;
645}
646
647static void skip_address_key(const char **p) {
648 assert(p);
649 assert(*p);
650
89ffcd2a
LP
651 *p += strcspn(*p, ",");
652
653 if (**p == ',')
313cefa1 654 (*p)++;
de1c301e
LP
655}
656
2fd9ae2e
LP
657static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
658 _cleanup_free_ char *path = NULL, *abstract = NULL;
659 size_t l;
de1c301e
LP
660 int r;
661
662 assert(b);
2fd9ae2e
LP
663 assert(p);
664 assert(*p);
665 assert(guid);
de1c301e 666
945c2931 667 while (!IN_SET(**p, 0, ';')) {
2fd9ae2e
LP
668 r = parse_address_key(p, "guid", guid);
669 if (r < 0)
670 return r;
671 else if (r > 0)
672 continue;
de1c301e 673
2fd9ae2e
LP
674 r = parse_address_key(p, "path", &path);
675 if (r < 0)
676 return r;
677 else if (r > 0)
678 continue;
de1c301e 679
2fd9ae2e
LP
680 r = parse_address_key(p, "abstract", &abstract);
681 if (r < 0)
682 return r;
683 else if (r > 0)
684 continue;
de1c301e 685
2fd9ae2e
LP
686 skip_address_key(p);
687 }
de1c301e 688
2fd9ae2e
LP
689 if (!path && !abstract)
690 return -EINVAL;
de1c301e 691
2fd9ae2e
LP
692 if (path && abstract)
693 return -EINVAL;
694
695 if (path) {
696 l = strlen(path);
697 if (l > sizeof(b->sockaddr.un.sun_path))
698 return -E2BIG;
de1c301e 699
2fd9ae2e
LP
700 b->sockaddr.un.sun_family = AF_UNIX;
701 strncpy(b->sockaddr.un.sun_path, path, sizeof(b->sockaddr.un.sun_path));
702 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l;
703 } else if (abstract) {
704 l = strlen(abstract);
705 if (l > sizeof(b->sockaddr.un.sun_path) - 1)
706 return -E2BIG;
707
708 b->sockaddr.un.sun_family = AF_UNIX;
709 b->sockaddr.un.sun_path[0] = 0;
710 strncpy(b->sockaddr.un.sun_path+1, abstract, sizeof(b->sockaddr.un.sun_path)-1);
711 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
712 }
713
694859b5
LP
714 b->is_local = true;
715
2fd9ae2e
LP
716 return 0;
717}
718
719static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
720 _cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
2fd9ae2e 721 int r;
b92bea5d
ZJS
722 struct addrinfo *result, hints = {
723 .ai_socktype = SOCK_STREAM,
724 .ai_flags = AI_ADDRCONFIG,
725 };
2fd9ae2e
LP
726
727 assert(b);
728 assert(p);
729 assert(*p);
730 assert(guid);
731
945c2931 732 while (!IN_SET(**p, 0, ';')) {
2fd9ae2e
LP
733 r = parse_address_key(p, "guid", guid);
734 if (r < 0)
735 return r;
736 else if (r > 0)
737 continue;
738
739 r = parse_address_key(p, "host", &host);
740 if (r < 0)
741 return r;
742 else if (r > 0)
743 continue;
744
745 r = parse_address_key(p, "port", &port);
746 if (r < 0)
747 return r;
748 else if (r > 0)
749 continue;
750
751 r = parse_address_key(p, "family", &family);
752 if (r < 0)
753 return r;
754 else if (r > 0)
755 continue;
756
757 skip_address_key(p);
758 }
759
760 if (!host || !port)
761 return -EINVAL;
762
2fd9ae2e
LP
763 if (family) {
764 if (streq(family, "ipv4"))
765 hints.ai_family = AF_INET;
766 else if (streq(family, "ipv6"))
767 hints.ai_family = AF_INET6;
768 else
769 return -EINVAL;
770 }
771
772 r = getaddrinfo(host, port, &hints, &result);
773 if (r == EAI_SYSTEM)
774 return -errno;
775 else if (r != 0)
776 return -EADDRNOTAVAIL;
777
778 memcpy(&b->sockaddr, result->ai_addr, result->ai_addrlen);
779 b->sockaddr_size = result->ai_addrlen;
780
781 freeaddrinfo(result);
782
694859b5
LP
783 b->is_local = false;
784
2fd9ae2e
LP
785 return 0;
786}
787
788static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
789 char *path = NULL;
790 unsigned n_argv = 0, j;
791 char **argv = NULL;
821e0756 792 size_t allocated = 0;
2fd9ae2e
LP
793 int r;
794
795 assert(b);
796 assert(p);
797 assert(*p);
798 assert(guid);
799
945c2931 800 while (!IN_SET(**p, 0, ';')) {
2fd9ae2e
LP
801 r = parse_address_key(p, "guid", guid);
802 if (r < 0)
803 goto fail;
804 else if (r > 0)
805 continue;
806
807 r = parse_address_key(p, "path", &path);
808 if (r < 0)
809 goto fail;
810 else if (r > 0)
811 continue;
812
813 if (startswith(*p, "argv")) {
814 unsigned ul;
815
816 errno = 0;
817 ul = strtoul(*p + 4, (char**) p, 10);
8333c77e 818 if (errno > 0 || **p != '=' || ul > 256) {
2fd9ae2e
LP
819 r = -EINVAL;
820 goto fail;
821 }
822
313cefa1 823 (*p)++;
2fd9ae2e
LP
824
825 if (ul >= n_argv) {
821e0756 826 if (!GREEDY_REALLOC0(argv, allocated, ul + 2)) {
2fd9ae2e
LP
827 r = -ENOMEM;
828 goto fail;
829 }
830
2fd9ae2e
LP
831 n_argv = ul + 1;
832 }
833
834 r = parse_address_key(p, NULL, argv + ul);
de1c301e 835 if (r < 0)
2fd9ae2e 836 goto fail;
de1c301e 837
2fd9ae2e 838 continue;
de1c301e
LP
839 }
840
2fd9ae2e
LP
841 skip_address_key(p);
842 }
de1c301e 843
5a0f6033
LP
844 if (!path) {
845 r = -EINVAL;
2fd9ae2e 846 goto fail;
5a0f6033 847 }
de1c301e 848
2fd9ae2e
LP
849 /* Make sure there are no holes in the array, with the
850 * exception of argv[0] */
851 for (j = 1; j < n_argv; j++)
852 if (!argv[j]) {
853 r = -EINVAL;
854 goto fail;
855 }
856
857 if (argv && argv[0] == NULL) {
858 argv[0] = strdup(path);
859 if (!argv[0]) {
860 r = -ENOMEM;
861 goto fail;
862 }
863 }
de1c301e 864
2fd9ae2e
LP
865 b->exec_path = path;
866 b->exec_argv = argv;
694859b5
LP
867
868 b->is_local = false;
869
2fd9ae2e 870 return 0;
de1c301e 871
2fd9ae2e
LP
872fail:
873 for (j = 0; j < n_argv; j++)
874 free(argv[j]);
875
876 free(argv);
877 free(path);
878 return r;
879}
880
bc9fd78c 881static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) {
ee502e0c 882 _cleanup_free_ char *machine = NULL, *pid = NULL;
a7893c6b
LP
883 int r;
884
885 assert(b);
886 assert(p);
887 assert(*p);
888 assert(guid);
889
945c2931 890 while (!IN_SET(**p, 0, ';')) {
a7893c6b
LP
891 r = parse_address_key(p, "guid", guid);
892 if (r < 0)
893 return r;
894 else if (r > 0)
895 continue;
896
897 r = parse_address_key(p, "machine", &machine);
898 if (r < 0)
899 return r;
900 else if (r > 0)
901 continue;
902
ee502e0c
LP
903 r = parse_address_key(p, "pid", &pid);
904 if (r < 0)
905 return r;
906 else if (r > 0)
907 continue;
908
a7893c6b
LP
909 skip_address_key(p);
910 }
911
ee502e0c 912 if (!machine == !pid)
a7893c6b
LP
913 return -EINVAL;
914
ee502e0c
LP
915 if (machine) {
916 if (!machine_name_is_valid(machine))
917 return -EINVAL;
b6741478 918
f9ecfd3b 919 free_and_replace(b->machine, machine);
ee502e0c 920 } else {
a1e58e8e 921 b->machine = mfree(b->machine);
ee502e0c
LP
922 }
923
924 if (pid) {
925 r = parse_pid(pid, &b->nspid);
926 if (r < 0)
927 return r;
928 } else
929 b->nspid = 0;
a7893c6b
LP
930
931 b->sockaddr.un.sun_family = AF_UNIX;
15ca0a42 932 /* Note that we use the old /var/run prefix here, to increase compatibility with really old containers */
df1e0204 933 strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
fc2fffe7 934 b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
694859b5 935 b->is_local = false;
a7893c6b
LP
936
937 return 0;
938}
939
2fd9ae2e
LP
940static void bus_reset_parsed_address(sd_bus *b) {
941 assert(b);
942
943 zero(b->sockaddr);
944 b->sockaddr_size = 0;
ba243e51
NK
945 b->exec_argv = strv_free(b->exec_argv);
946 b->exec_path = mfree(b->exec_path);
98178d39 947 b->server_id = SD_ID128_NULL;
ba243e51 948 b->machine = mfree(b->machine);
ee502e0c 949 b->nspid = 0;
2fd9ae2e
LP
950}
951
952static int bus_parse_next_address(sd_bus *b) {
953 _cleanup_free_ char *guid = NULL;
954 const char *a;
955 int r;
956
957 assert(b);
958
959 if (!b->address)
960 return 0;
961 if (b->address[b->address_index] == 0)
962 return 0;
963
964 bus_reset_parsed_address(b);
965
966 a = b->address + b->address_index;
de1c301e 967
2fd9ae2e 968 while (*a != 0) {
de1c301e 969
2fd9ae2e
LP
970 if (*a == ';') {
971 a++;
972 continue;
de1c301e
LP
973 }
974
2fd9ae2e
LP
975 if (startswith(a, "unix:")) {
976 a += 5;
de1c301e 977
2fd9ae2e 978 r = parse_unix_address(b, &a, &guid);
de1c301e
LP
979 if (r < 0)
980 return r;
2fd9ae2e 981 break;
de1c301e 982
2fd9ae2e 983 } else if (startswith(a, "tcp:")) {
de1c301e 984
2fd9ae2e
LP
985 a += 4;
986 r = parse_tcp_address(b, &a, &guid);
de1c301e
LP
987 if (r < 0)
988 return r;
de1c301e 989
2fd9ae2e
LP
990 break;
991
992 } else if (startswith(a, "unixexec:")) {
993
994 a += 9;
995 r = parse_exec_address(b, &a, &guid);
de1c301e
LP
996 if (r < 0)
997 return r;
de1c301e 998
2fd9ae2e 999 break;
de1c301e 1000
de33fc62 1001 } else if (startswith(a, "x-machine-unix:")) {
bc9fd78c 1002
146d4773 1003 a += 15;
bc9fd78c
LP
1004 r = parse_container_unix_address(b, &a, &guid);
1005 if (r < 0)
1006 return r;
1007
6629161f 1008 break;
de1c301e
LP
1009 }
1010
2fd9ae2e
LP
1011 a = strchr(a, ';');
1012 if (!a)
1013 return 0;
de1c301e
LP
1014 }
1015
1016 if (guid) {
98178d39 1017 r = sd_id128_from_string(guid, &b->server_id);
de1c301e
LP
1018 if (r < 0)
1019 return r;
1020 }
1021
2fd9ae2e 1022 b->address_index = a - b->address;
de1c301e
LP
1023 return 1;
1024}
1025
a7e3212d 1026static int bus_start_address(sd_bus *b) {
2fd9ae2e
LP
1027 int r;
1028
1029 assert(b);
1030
1031 for (;;) {
8a5cd31e
LP
1032 bus_close_io_fds(b);
1033 bus_close_inotify_fd(b);
a7e3212d 1034
a132bef0
ZJS
1035 /* If you provide multiple different bus-addresses, we
1036 * try all of them in order and use the first one that
1037 * succeeds. */
15442912 1038
1e05d493 1039 if (b->exec_path)
a7893c6b 1040 r = bus_socket_exec(b);
a132bef0
ZJS
1041 else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC)
1042 r = bus_container_connect_socket(b);
a132bef0
ZJS
1043 else if (b->sockaddr.sa.sa_family != AF_UNSPEC)
1044 r = bus_socket_connect(b);
a132bef0
ZJS
1045 else
1046 goto next;
1047
1048 if (r >= 0) {
8a5cd31e
LP
1049 int q;
1050
1051 q = bus_attach_io_events(b);
1052 if (q < 0)
1053 return q;
1054
1055 q = bus_attach_inotify_event(b);
1056 if (q < 0)
1057 return q;
1058
1059 return r;
2fd9ae2e
LP
1060 }
1061
a132bef0
ZJS
1062 b->last_connect_error = -r;
1063
1064 next:
2fd9ae2e
LP
1065 r = bus_parse_next_address(b);
1066 if (r < 0)
1067 return r;
1068 if (r == 0)
a132bef0 1069 return b->last_connect_error > 0 ? -b->last_connect_error : -ECONNREFUSED;
de1c301e
LP
1070 }
1071}
1072
a7e3212d
LP
1073int bus_next_address(sd_bus *b) {
1074 assert(b);
1075
1076 bus_reset_parsed_address(b);
1077 return bus_start_address(b);
1078}
1079
021a1e78 1080static int bus_start_fd(sd_bus *b) {
6629161f 1081 struct stat st;
021a1e78
LP
1082 int r;
1083
1084 assert(b);
e82c9509
LP
1085 assert(b->input_fd >= 0);
1086 assert(b->output_fd >= 0);
021a1e78 1087
e82c9509 1088 r = fd_nonblock(b->input_fd, true);
021a1e78
LP
1089 if (r < 0)
1090 return r;
1091
e82c9509 1092 r = fd_cloexec(b->input_fd, true);
021a1e78
LP
1093 if (r < 0)
1094 return r;
1095
e82c9509
LP
1096 if (b->input_fd != b->output_fd) {
1097 r = fd_nonblock(b->output_fd, true);
1098 if (r < 0)
1099 return r;
1100
1101 r = fd_cloexec(b->output_fd, true);
1102 if (r < 0)
1103 return r;
1104 }
1105
6629161f
LP
1106 if (fstat(b->input_fd, &st) < 0)
1107 return -errno;
1108
a132bef0 1109 return bus_socket_take_fd(b);
021a1e78
LP
1110}
1111
d9f644e2 1112_public_ int sd_bus_start(sd_bus *bus) {
021a1e78
LP
1113 int r;
1114
d6888822
LP
1115 assert_return(bus, -EINVAL);
1116 assert_return(bus->state == BUS_UNSET, -EPERM);
1117 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 1118
3e0e196e 1119 bus_set_state(bus, BUS_OPENING);
021a1e78 1120
2181a7f5
LP
1121 if (bus->is_server && bus->bus_client)
1122 return -EINVAL;
1123
e82c9509 1124 if (bus->input_fd >= 0)
021a1e78 1125 r = bus_start_fd(bus);
a132bef0 1126 else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->machine)
a7e3212d 1127 r = bus_start_address(bus);
021a1e78
LP
1128 else
1129 return -EINVAL;
1130
db9bb83f
LP
1131 if (r < 0) {
1132 sd_bus_close(bus);
021a1e78 1133 return r;
db9bb83f 1134 }
021a1e78
LP
1135
1136 return bus_send_hello(bus);
1137}
1138
af08d2f9
LP
1139_public_ int sd_bus_open(sd_bus **ret) {
1140 const char *e;
1141 sd_bus *b;
1142 int r;
1143
1144 assert_return(ret, -EINVAL);
1145
1146 /* Let's connect to the starter bus if it is set, and
1147 * otherwise to the bus that is appropropriate for the scope
1148 * we are running in */
1149
1150 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
1151 if (e) {
1152 if (streq(e, "system"))
1153 return sd_bus_open_system(ret);
09365592 1154 else if (STR_IN_SET(e, "session", "user"))
af08d2f9
LP
1155 return sd_bus_open_user(ret);
1156 }
1157
1158 e = secure_getenv("DBUS_STARTER_ADDRESS");
1159 if (!e) {
1160 if (cg_pid_get_owner_uid(0, NULL) >= 0)
1161 return sd_bus_open_user(ret);
1162 else
1163 return sd_bus_open_system(ret);
1164 }
1165
1166 r = sd_bus_new(&b);
1167 if (r < 0)
1168 return r;
1169
1170 r = sd_bus_set_address(b, e);
1171 if (r < 0)
1172 goto fail;
1173
1174 b->bus_client = true;
1175
1176 /* We don't know whether the bus is trusted or not, so better
1177 * be safe, and authenticate everything */
1178 b->trusted = false;
694859b5 1179 b->is_local = false;
cf226cfc 1180 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
af08d2f9
LP
1181
1182 r = sd_bus_start(b);
1183 if (r < 0)
1184 goto fail;
1185
1186 *ret = b;
1187 return 0;
1188
1189fail:
1190 bus_free(b);
1191 return r;
1192}
1193
09365592 1194int bus_set_address_system(sd_bus *b) {
de1c301e 1195 const char *e;
09365592
LP
1196 assert(b);
1197
1198 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
1199 if (e)
1200 return sd_bus_set_address(b, e);
1201
057171ef 1202 return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS);
09365592
LP
1203}
1204
1205_public_ int sd_bus_open_system(sd_bus **ret) {
de1c301e
LP
1206 sd_bus *b;
1207 int r;
1208
d6888822 1209 assert_return(ret, -EINVAL);
de1c301e 1210
021a1e78
LP
1211 r = sd_bus_new(&b);
1212 if (r < 0)
1213 return r;
1214
09365592 1215 r = bus_set_address_system(b);
e3dd987c
LP
1216 if (r < 0)
1217 goto fail;
de1c301e 1218
94bbf1ba 1219 b->bus_client = true;
5972fe95 1220 b->is_system = true;
021a1e78 1221
adacb957
LP
1222 /* Let's do per-method access control on the system bus. We
1223 * need the caller's UID and capability set for that. */
1224 b->trusted = false;
cf226cfc 1225 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
694859b5 1226 b->is_local = true;
adacb957 1227
021a1e78
LP
1228 r = sd_bus_start(b);
1229 if (r < 0)
1230 goto fail;
de1c301e
LP
1231
1232 *ret = b;
1233 return 0;
021a1e78
LP
1234
1235fail:
1236 bus_free(b);
1237 return r;
de1c301e
LP
1238}
1239
09365592 1240int bus_set_address_user(sd_bus *b) {
de1c301e 1241 const char *e;
a132bef0 1242 _cleanup_free_ char *ee = NULL, *s = NULL;
de1c301e 1243
09365592 1244 assert(b);
021a1e78 1245
6c03089c 1246 e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
09365592
LP
1247 if (e)
1248 return sd_bus_set_address(b, e);
1249
1250 e = secure_getenv("XDG_RUNTIME_DIR");
a132bef0
ZJS
1251 if (!e)
1252 return -ENOENT;
e3dd987c 1253
a132bef0
ZJS
1254 ee = bus_address_escape(e);
1255 if (!ee)
1256 return -ENOMEM;
de1c301e 1257
15ca0a42 1258 if (asprintf(&s, DEFAULT_USER_BUS_ADDRESS_FMT, ee) < 0)
09365592
LP
1259 return -ENOMEM;
1260
a132bef0
ZJS
1261 b->address = s;
1262 s = NULL;
1263
09365592
LP
1264 return 0;
1265}
1266
1267_public_ int sd_bus_open_user(sd_bus **ret) {
1268 sd_bus *b;
1269 int r;
1270
1271 assert_return(ret, -EINVAL);
1272
1273 r = sd_bus_new(&b);
1274 if (r < 0)
1275 return r;
1276
1277 r = bus_set_address_user(b);
1278 if (r < 0)
4f6631c8 1279 goto fail;
09365592 1280
94bbf1ba 1281 b->bus_client = true;
5972fe95 1282 b->is_user = true;
de1c301e 1283
adacb957
LP
1284 /* We don't do any per-method access control on the user
1285 * bus. */
1286 b->trusted = true;
694859b5 1287 b->is_local = true;
adacb957 1288
021a1e78 1289 r = sd_bus_start(b);
2571ead1
LP
1290 if (r < 0)
1291 goto fail;
de1c301e
LP
1292
1293 *ret = b;
1294 return 0;
2571ead1
LP
1295
1296fail:
021a1e78 1297 bus_free(b);
2571ead1 1298 return r;
de1c301e
LP
1299}
1300
09365592 1301int bus_set_address_system_remote(sd_bus *b, const char *host) {
0f8bd8de 1302 _cleanup_free_ char *e = NULL;
7f0d207d 1303 char *m = NULL, *c = NULL;
0f8bd8de 1304
09365592
LP
1305 assert(b);
1306 assert(host);
0f8bd8de 1307
7f0d207d
LP
1308 /* Let's see if we shall enter some container */
1309 m = strchr(host, ':');
1310 if (m) {
1311 m++;
1312
1313 /* Let's make sure this is not a port of some kind,
1314 * and is a valid machine name. */
1315 if (!in_charset(m, "0123456789") && machine_name_is_valid(m)) {
1316 char *t;
1317
1318 /* Cut out the host part */
1319 t = strndupa(host, m - host - 1);
1320 e = bus_address_escape(t);
1321 if (!e)
1322 return -ENOMEM;
1323
58c6e4a2 1324 c = strjoina(",argv5=--machine=", m);
7f0d207d
LP
1325 }
1326 }
1327
1328 if (!e) {
1329 e = bus_address_escape(host);
1330 if (!e)
1331 return -ENOMEM;
1332 }
0f8bd8de 1333
58c6e4a2 1334 b->address = strjoin("unixexec:path=ssh,argv1=-xT,argv2=--,argv3=", e, ",argv4=systemd-stdio-bridge", c);
09365592 1335 if (!b->address)
0f8bd8de 1336 return -ENOMEM;
a7893c6b 1337
09365592
LP
1338 return 0;
1339 }
1340
1341_public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
1342 sd_bus *bus;
1343 int r;
1344
1345 assert_return(host, -EINVAL);
1346 assert_return(ret, -EINVAL);
1347
a7893c6b 1348 r = sd_bus_new(&bus);
09365592 1349 if (r < 0)
a7893c6b 1350 return r;
a7893c6b 1351
09365592
LP
1352 r = bus_set_address_system_remote(bus, host);
1353 if (r < 0)
1354 goto fail;
1355
a7893c6b 1356 bus->bus_client = true;
09365592 1357 bus->trusted = false;
3acc1daf 1358 bus->is_system = true;
694859b5 1359 bus->is_local = false;
a7893c6b
LP
1360
1361 r = sd_bus_start(bus);
09365592
LP
1362 if (r < 0)
1363 goto fail;
a7893c6b
LP
1364
1365 *ret = bus;
1366 return 0;
09365592
LP
1367
1368fail:
1369 bus_free(bus);
1370 return r;
a7893c6b
LP
1371}
1372
de33fc62 1373int bus_set_address_system_machine(sd_bus *b, const char *machine) {
a7893c6b 1374 _cleanup_free_ char *e = NULL;
a7893c6b 1375
09365592
LP
1376 assert(b);
1377 assert(machine);
a7893c6b
LP
1378
1379 e = bus_address_escape(machine);
1380 if (!e)
1381 return -ENOMEM;
1382
a132bef0 1383 b->address = strjoin("x-machine-unix:machine=", e);
09365592 1384 if (!b->address)
a7893c6b 1385 return -ENOMEM;
0f8bd8de 1386
09365592
LP
1387 return 0;
1388}
1389
de33fc62 1390_public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) {
09365592
LP
1391 sd_bus *bus;
1392 int r;
1393
1394 assert_return(machine, -EINVAL);
1395 assert_return(ret, -EINVAL);
affcf189 1396 assert_return(machine_name_is_valid(machine), -EINVAL);
09365592 1397
0f8bd8de 1398 r = sd_bus_new(&bus);
09365592 1399 if (r < 0)
0f8bd8de 1400 return r;
0f8bd8de 1401
de33fc62 1402 r = bus_set_address_system_machine(bus, machine);
09365592
LP
1403 if (r < 0)
1404 goto fail;
1405
0f8bd8de 1406 bus->bus_client = true;
09365592 1407 bus->trusted = false;
3acc1daf 1408 bus->is_system = true;
694859b5 1409 bus->is_local = false;
0f8bd8de
LP
1410
1411 r = sd_bus_start(bus);
09365592
LP
1412 if (r < 0)
1413 goto fail;
0f8bd8de
LP
1414
1415 *ret = bus;
1416 return 0;
09365592
LP
1417
1418fail:
1419 bus_free(bus);
1420 return r;
0f8bd8de
LP
1421}
1422
d9f644e2 1423_public_ void sd_bus_close(sd_bus *bus) {
0e586eae 1424
de1c301e
LP
1425 if (!bus)
1426 return;
d5a2b9a6
LP
1427 if (bus->state == BUS_CLOSED)
1428 return;
1429 if (bus_pid_changed(bus))
f54514f3
LP
1430 return;
1431
3e0e196e 1432 bus_set_state(bus, BUS_CLOSED);
e82c9509 1433
40ca29a1
LP
1434 sd_bus_detach_event(bus);
1435
0e586eae
LP
1436 /* Drop all queued messages so that they drop references to
1437 * the bus object and the bus may be freed */
1438 bus_reset_queues(bus);
1439
8a5cd31e
LP
1440 bus_close_io_fds(bus);
1441 bus_close_inotify_fd(bus);
de1c301e
LP
1442}
1443
03976f7b
LP
1444_public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
1445
1446 if (!bus)
1447 return NULL;
1448
1449 sd_bus_flush(bus);
1450 sd_bus_close(bus);
1451
1452 return sd_bus_unref(bus);
1453}
1454
98c5bbc8 1455void bus_enter_closing(sd_bus *bus) {
718db961
LP
1456 assert(bus);
1457
8a5cd31e 1458 if (!IN_SET(bus->state, BUS_WATCH_BIND, BUS_OPENING, BUS_AUTHENTICATING, BUS_HELLO, BUS_RUNNING))
718db961
LP
1459 return;
1460
3e0e196e 1461 bus_set_state(bus, BUS_CLOSING);
718db961
LP
1462}
1463
d9f644e2 1464_public_ sd_bus *sd_bus_ref(sd_bus *bus) {
4afd3348
LP
1465
1466 if (!bus)
1467 return NULL;
de1c301e 1468
e4ee6e5c 1469 assert_se(REFCNT_INC(bus->n_ref) >= 2);
de1c301e 1470
de1c301e
LP
1471 return bus;
1472}
1473
d9f644e2 1474_public_ sd_bus *sd_bus_unref(sd_bus *bus) {
b7fc42e0 1475 unsigned i;
5b1bc83f
LP
1476
1477 if (!bus)
1478 return NULL;
de1c301e 1479
f389bf15
LP
1480 i = REFCNT_DEC(bus->n_ref);
1481 if (i > 0)
1482 return NULL;
1483
1484 bus_free(bus);
de1c301e
LP
1485 return NULL;
1486}
1487
d9f644e2 1488_public_ int sd_bus_is_open(sd_bus *bus) {
d6888822
LP
1489
1490 assert_return(bus, -EINVAL);
1491 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 1492
f54514f3 1493 return BUS_IS_OPEN(bus->state);
e3017af9
LP
1494}
1495
bdbc8669
LP
1496_public_ int sd_bus_is_ready(sd_bus *bus) {
1497 assert_return(bus, -EINVAL);
1498 assert_return(!bus_pid_changed(bus), -ECHILD);
1499
1500 return bus->state == BUS_RUNNING;
1501}
1502
d9f644e2 1503_public_ int sd_bus_can_send(sd_bus *bus, char type) {
d728d708
LP
1504 int r;
1505
d6888822
LP
1506 assert_return(bus, -EINVAL);
1507 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
1508 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1509
c7db1984 1510 if (bus->is_monitor)
09365592
LP
1511 return 0;
1512
d728d708 1513 if (type == SD_BUS_TYPE_UNIX_FD) {
c7db1984 1514 if (!bus->accept_fd)
021a1e78
LP
1515 return 0;
1516
20902f3e 1517 r = bus_ensure_running(bus);
d728d708
LP
1518 if (r < 0)
1519 return r;
de1c301e 1520
d728d708
LP
1521 return bus->can_fds;
1522 }
1523
1524 return bus_type_is_valid(type);
de1c301e
LP
1525}
1526
5c302692 1527_public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) {
d728d708 1528 int r;
de1c301e 1529
d6888822 1530 assert_return(bus, -EINVAL);
f7fce345 1531 assert_return(id, -EINVAL);
d6888822 1532 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1533
20902f3e 1534 r = bus_ensure_running(bus);
d728d708
LP
1535 if (r < 0)
1536 return r;
de1c301e 1537
f7fce345 1538 *id = bus->server_id;
d728d708 1539 return 0;
de1c301e
LP
1540}
1541
3df7a7e6 1542static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
48ef41a3
LP
1543 int r;
1544
7adc46fc 1545 assert(b);
de1c301e
LP
1546 assert(m);
1547
aea93deb
LP
1548 if (m->sealed) {
1549 /* If we copy the same message to multiple
693eb9a2 1550 * destinations, avoid using the same cookie
aea93deb 1551 * numbers. */
693eb9a2 1552 b->cookie = MAX(b->cookie, BUS_MESSAGE_COOKIE(m));
de1c301e 1553 return 0;
aea93deb 1554 }
de1c301e 1555
3df7a7e6
LP
1556 if (timeout == 0)
1557 timeout = BUS_DEFAULT_TIMEOUT;
1558
48ef41a3
LP
1559 if (!m->sender && b->patch_sender) {
1560 r = sd_bus_message_set_sender(m, b->patch_sender);
1561 if (r < 0)
1562 return r;
1563 }
1564
75bcbcf2 1565 return sd_bus_message_seal(m, ++b->cookie, timeout);
de1c301e
LP
1566}
1567
e1c433c6 1568static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
908b8a42
DH
1569 bool remarshal = false;
1570
e1c433c6
LP
1571 assert(b);
1572
908b8a42
DH
1573 /* wrong packet version */
1574 if (b->message_version != 0 && b->message_version != (*m)->header->version)
1575 remarshal = true;
1576
1577 /* wrong packet endianness */
1578 if (b->message_endian != 0 && b->message_endian != (*m)->header->endian)
1579 remarshal = true;
1580
908b8a42 1581 return remarshal ? bus_message_remarshal(b, m) : 0;
e1c433c6
LP
1582}
1583
7adc46fc
LP
1584int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
1585 assert(b);
1586 assert(m);
1587
52cd5877
LP
1588 /* Fake some timestamps, if they were requested, and not
1589 * already initialized */
c7db1984 1590 if (b->attach_timestamp) {
52cd5877
LP
1591 if (m->realtime <= 0)
1592 m->realtime = now(CLOCK_REALTIME);
1593
1594 if (m->monotonic <= 0)
1595 m->monotonic = now(CLOCK_MONOTONIC);
1596 }
1597
7adc46fc
LP
1598 /* The bus specification says the serial number cannot be 0,
1599 * hence let's fill something in for synthetic messages. Since
1600 * synthetic messages might have a fake sender and we don't
1601 * want to interfere with the real sender's serial numbers we
6f285378 1602 * pick a fixed, artificial one. We use (uint32_t) -1 rather
7adc46fc
LP
1603 * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
1604 * even though kdbus can do 64bit. */
75bcbcf2 1605 return sd_bus_message_seal(m, 0xFFFFFFFFULL, 0);
7adc46fc
LP
1606}
1607
66baf8c6 1608static int bus_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
2e3db52d
LP
1609 int r;
1610
718db961 1611 assert(bus);
2e3db52d 1612 assert(m);
718db961 1613
a132bef0 1614 r = bus_socket_write_message(bus, m, idx);
2e3db52d
LP
1615 if (r <= 0)
1616 return r;
1617
a132bef0 1618 if (*idx >= BUS_MESSAGE_SIZE(m))
e32fd6b4 1619 log_debug("Sent message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s",
2e3db52d
LP
1620 bus_message_type_to_string(m->header->type),
1621 strna(sd_bus_message_get_sender(m)),
1622 strna(sd_bus_message_get_destination(m)),
1623 strna(sd_bus_message_get_path(m)),
1624 strna(sd_bus_message_get_interface(m)),
1625 strna(sd_bus_message_get_member(m)),
42c4ebcb
LP
1626 BUS_MESSAGE_COOKIE(m),
1627 m->reply_cookie,
e32fd6b4 1628 strna(m->root_container.signature),
e28d0865 1629 strna(m->error.name),
2e3db52d
LP
1630 strna(m->error.message));
1631
1632 return r;
718db961
LP
1633}
1634
de1c301e 1635static int dispatch_wqueue(sd_bus *bus) {
e3017af9 1636 int r, ret = 0;
de1c301e
LP
1637
1638 assert(bus);
945c2931 1639 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
de1c301e 1640
de1c301e
LP
1641 while (bus->wqueue_size > 0) {
1642
66baf8c6 1643 r = bus_write_message(bus, bus->wqueue[0], &bus->windex);
718db961 1644 if (r < 0)
de1c301e 1645 return r;
718db961 1646 else if (r == 0)
e3017af9
LP
1647 /* Didn't do anything this time */
1648 return ret;
a132bef0 1649 else if (bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
de1c301e
LP
1650 /* Fully written. Let's drop the entry from
1651 * the queue.
1652 *
1653 * This isn't particularly optimized, but
1654 * well, this is supposed to be our worst-case
1655 * buffer only, and the socket buffer is
1656 * supposed to be our primary buffer, and if
1657 * it got full, then all bets are off
1658 * anyway. */
1659
313cefa1 1660 bus->wqueue_size--;
c4e6e242 1661 sd_bus_message_unref(bus->wqueue[0]);
de1c301e
LP
1662 memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
1663 bus->windex = 0;
1664
e3017af9 1665 ret = 1;
de1c301e
LP
1666 }
1667 }
1668
e3017af9 1669 return ret;
de1c301e
LP
1670}
1671
766c5809 1672static int bus_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
7d22c717
LP
1673 assert(bus);
1674
a132bef0 1675 return bus_socket_read_message(bus);
7d22c717
LP
1676}
1677
7adc46fc 1678int bus_rqueue_make_room(sd_bus *bus) {
821e0756 1679 assert(bus);
7d22c717 1680
821e0756 1681 if (bus->rqueue_size >= BUS_RQUEUE_MAX)
7d22c717
LP
1682 return -ENOBUFS;
1683
821e0756 1684 if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_allocated, bus->rqueue_size + 1))
7d22c717
LP
1685 return -ENOMEM;
1686
7d22c717
LP
1687 return 0;
1688}
1689
766c5809 1690static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) {
e3017af9 1691 int r, ret = 0;
de1c301e
LP
1692
1693 assert(bus);
1694 assert(m);
945c2931 1695 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
de1c301e 1696
766c5809
LP
1697 /* Note that the priority logic is only available on kdbus,
1698 * where the rqueue is unused. We check the rqueue here
1699 * anyway, because it's simple... */
1700
7d22c717
LP
1701 for (;;) {
1702 if (bus->rqueue_size > 0) {
1703 /* Dispatch a queued message */
de1c301e 1704
7d22c717 1705 *m = bus->rqueue[0];
313cefa1 1706 bus->rqueue_size--;
7d22c717
LP
1707 memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
1708 return 1;
1709 }
de1c301e 1710
7d22c717 1711 /* Try to read a new message */
766c5809 1712 r = bus_read_message(bus, hint_priority, priority);
718db961 1713 if (r < 0)
e3017af9 1714 return r;
e3017af9
LP
1715 if (r == 0)
1716 return ret;
de1c301e 1717
2e8d788c 1718 ret = 1;
7d22c717 1719 }
de1c301e
LP
1720}
1721
66baf8c6 1722_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
4afd3348 1723 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e
LP
1724 int r;
1725
d6888822 1726 assert_return(m, -EINVAL);
9030ca46
LP
1727
1728 if (!bus)
1729 bus = m->bus;
1730
d6888822 1731 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 1732
a3d59cd1
LP
1733 if (!BUS_IS_OPEN(bus->state))
1734 return -ENOTCONN;
1735
021a1e78
LP
1736 if (m->n_fds > 0) {
1737 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1738 if (r < 0)
1739 return r;
1740 if (r == 0)
15411c0c 1741 return -EOPNOTSUPP;
021a1e78 1742 }
de1c301e 1743
693eb9a2 1744 /* If the cookie number isn't kept, then we know that no reply
29f6aadd 1745 * is expected */
693eb9a2 1746 if (!cookie && !m->sealed)
0461f8cd 1747 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
29f6aadd 1748
3df7a7e6 1749 r = bus_seal_message(bus, m, 0);
de1c301e
LP
1750 if (r < 0)
1751 return r;
1752
441d56a1 1753 /* Remarshall if we have to. This will possibly unref the
e1c433c6
LP
1754 * message and place a replacement in m */
1755 r = bus_remarshal_message(bus, &m);
1756 if (r < 0)
1757 return r;
1758
5407f2de
LP
1759 /* If this is a reply and no reply was requested, then let's
1760 * suppress this, if we can */
997eadb5
LP
1761 if (m->dont_send)
1762 goto finish;
5407f2de 1763
945c2931 1764 if (IN_SET(bus->state, BUS_RUNNING, BUS_HELLO) && bus->wqueue_size <= 0) {
de1c301e
LP
1765 size_t idx = 0;
1766
66baf8c6 1767 r = bus_write_message(bus, m, &idx);
32f46480 1768 if (r < 0) {
103a5027 1769 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
32f46480 1770 bus_enter_closing(bus);
441d56a1
LP
1771 return -ECONNRESET;
1772 }
32f46480 1773
de1c301e 1774 return r;
997eadb5
LP
1775 }
1776
a132bef0 1777 if (idx < BUS_MESSAGE_SIZE(m)) {
de1c301e
LP
1778 /* Wasn't fully written. So let's remember how
1779 * much was written. Note that the first entry
1780 * of the wqueue array is always allocated so
1781 * that we always can remember how much was
1782 * written. */
1783 bus->wqueue[0] = sd_bus_message_ref(m);
1784 bus->wqueue_size = 1;
1785 bus->windex = idx;
1786 }
997eadb5 1787
de1c301e 1788 } else {
de1c301e
LP
1789 /* Just append it to the queue. */
1790
25220239 1791 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
de1c301e
LP
1792 return -ENOBUFS;
1793
821e0756 1794 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
de1c301e
LP
1795 return -ENOMEM;
1796
313cefa1 1797 bus->wqueue[bus->wqueue_size++] = sd_bus_message_ref(m);
de1c301e
LP
1798 }
1799
997eadb5 1800finish:
693eb9a2
LP
1801 if (cookie)
1802 *cookie = BUS_MESSAGE_COOKIE(m);
de1c301e 1803
7a37d625 1804 return 1;
de1c301e
LP
1805}
1806
693eb9a2 1807_public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) {
911121a7
LP
1808 int r;
1809
911121a7 1810 assert_return(m, -EINVAL);
9030ca46
LP
1811
1812 if (!bus)
1813 bus = m->bus;
1814
911121a7
LP
1815 assert_return(!bus_pid_changed(bus), -ECHILD);
1816
a3d59cd1
LP
1817 if (!BUS_IS_OPEN(bus->state))
1818 return -ENOTCONN;
1819
911121a7
LP
1820 if (!streq_ptr(m->destination, destination)) {
1821
1822 if (!destination)
1823 return -EEXIST;
1824
1825 r = sd_bus_message_set_destination(m, destination);
1826 if (r < 0)
1827 return r;
1828 }
1829
693eb9a2 1830 return sd_bus_send(bus, m, cookie);
911121a7
LP
1831}
1832
ac8029fc
LP
1833static usec_t calc_elapse(sd_bus *bus, uint64_t usec) {
1834 assert(bus);
1835
de1c301e
LP
1836 if (usec == (uint64_t) -1)
1837 return 0;
1838
ac8029fc
LP
1839 /* We start all timeouts the instant we enter BUS_HELLO/BUS_RUNNING state, so that the don't run in parallel
1840 * with any connection setup states. Hence, if a method callback is started earlier than that we just store the
1841 * relative timestamp, and afterwards the absolute one. */
1842
1843 if (IN_SET(bus->state, BUS_WATCH_BIND, BUS_OPENING, BUS_AUTHENTICATING))
1844 return usec;
1845 else
1846 return now(CLOCK_MONOTONIC) + usec;
de1c301e
LP
1847}
1848
e3017af9
LP
1849static int timeout_compare(const void *a, const void *b) {
1850 const struct reply_callback *x = a, *y = b;
1851
ac8029fc 1852 if (x->timeout_usec != 0 && y->timeout_usec == 0)
e3017af9
LP
1853 return -1;
1854
ac8029fc 1855 if (x->timeout_usec == 0 && y->timeout_usec != 0)
e3017af9
LP
1856 return 1;
1857
ac8029fc 1858 if (x->timeout_usec < y->timeout_usec)
e3017af9
LP
1859 return -1;
1860
ac8029fc 1861 if (x->timeout_usec > y->timeout_usec)
e3017af9
LP
1862 return 1;
1863
1864 return 0;
1865}
1866
c49b30a2 1867_public_ int sd_bus_call_async(
de1c301e 1868 sd_bus *bus,
19befb2d 1869 sd_bus_slot **slot,
e1c433c6 1870 sd_bus_message *_m,
52f3ba91 1871 sd_bus_message_handler_t callback,
de1c301e 1872 void *userdata,
19befb2d 1873 uint64_t usec) {
de1c301e 1874
4afd3348
LP
1875 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
1876 _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *s = NULL;
de1c301e
LP
1877 int r;
1878
d6888822 1879 assert_return(m, -EINVAL);
40ca29a1 1880 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
dbc526f0 1881 assert_return(!m->sealed || (!!callback == !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)), -EINVAL);
9030ca46
LP
1882
1883 if (!bus)
1884 bus = m->bus;
1885
d6888822 1886 assert_return(!bus_pid_changed(bus), -ECHILD);
89ffcd2a 1887
a3d59cd1
LP
1888 if (!BUS_IS_OPEN(bus->state))
1889 return -ENOTCONN;
1890
dbc526f0
LP
1891 /* If no callback is specified and there's no interest in a slot, then there's no reason to ask for a reply */
1892 if (!callback && !slot && !m->sealed)
1893 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
1894
c9fe4af7 1895 r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
89ffcd2a
LP
1896 if (r < 0)
1897 return r;
de1c301e 1898
3df7a7e6
LP
1899 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1900 if (r < 0)
1901 return r;
e3017af9 1902
3df7a7e6 1903 r = bus_seal_message(bus, m, usec);
de1c301e
LP
1904 if (r < 0)
1905 return r;
1906
e1c433c6
LP
1907 r = bus_remarshal_message(bus, &m);
1908 if (r < 0)
1909 return r;
1910
dbc526f0
LP
1911 if (slot || callback) {
1912 s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
1913 if (!s)
1914 return -ENOMEM;
de1c301e 1915
dbc526f0 1916 s->reply_callback.callback = callback;
de1c301e 1917
dbc526f0
LP
1918 s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
1919 r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
e3017af9 1920 if (r < 0) {
dbc526f0 1921 s->reply_callback.cookie = 0;
e3017af9
LP
1922 return r;
1923 }
dbc526f0
LP
1924
1925 s->reply_callback.timeout_usec = calc_elapse(bus, m->timeout);
1926 if (s->reply_callback.timeout_usec != 0) {
1927 r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
1928 if (r < 0) {
1929 s->reply_callback.timeout_usec = 0;
1930 return r;
1931 }
1932 }
e3017af9
LP
1933 }
1934
dbc526f0 1935 r = sd_bus_send(bus, m, s ? &s->reply_callback.cookie : NULL);
19befb2d 1936 if (r < 0)
de1c301e 1937 return r;
de1c301e 1938
19befb2d
LP
1939 if (slot)
1940 *slot = s;
1941 s = NULL;
e3017af9 1942
19befb2d 1943 return r;
de1c301e
LP
1944}
1945
20902f3e 1946int bus_ensure_running(sd_bus *bus) {
89ffcd2a
LP
1947 int r;
1948
1949 assert(bus);
1950
945c2931 1951 if (IN_SET(bus->state, BUS_UNSET, BUS_CLOSED, BUS_CLOSING))
021a1e78 1952 return -ENOTCONN;
d728d708
LP
1953 if (bus->state == BUS_RUNNING)
1954 return 1;
89ffcd2a
LP
1955
1956 for (;;) {
1957 r = sd_bus_process(bus, NULL);
1958 if (r < 0)
1959 return r;
d728d708
LP
1960 if (bus->state == BUS_RUNNING)
1961 return 1;
e3017af9
LP
1962 if (r > 0)
1963 continue;
89ffcd2a
LP
1964
1965 r = sd_bus_wait(bus, (uint64_t) -1);
1966 if (r < 0)
1967 return r;
1968 }
1969}
1970
97f82db3 1971_public_ int sd_bus_call(
de1c301e 1972 sd_bus *bus,
97f82db3 1973 sd_bus_message *_m,
de1c301e
LP
1974 uint64_t usec,
1975 sd_bus_error *error,
1976 sd_bus_message **reply) {
1977
4afd3348 1978 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e 1979 usec_t timeout;
693eb9a2 1980 uint64_t cookie;
7d22c717
LP
1981 unsigned i;
1982 int r;
de1c301e 1983
759e02e7
LP
1984 bus_assert_return(m, -EINVAL, error);
1985 bus_assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL, error);
1986 bus_assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL, error);
1987 bus_assert_return(!bus_error_is_dirty(error), -EINVAL, error);
9030ca46
LP
1988
1989 if (!bus)
1990 bus = m->bus;
1991
759e02e7 1992 bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
97f82db3 1993
759e02e7
LP
1994 if (!BUS_IS_OPEN(bus->state)) {
1995 r = -ENOTCONN;
1996 goto fail;
1997 }
a3d59cd1 1998
97f82db3
KS
1999 r = bus_ensure_running(bus);
2000 if (r < 0)
759e02e7 2001 goto fail;
97f82db3 2002
a43b9ca3 2003 i = bus->rqueue_size;
97f82db3
KS
2004
2005 r = bus_seal_message(bus, m, usec);
2006 if (r < 0)
759e02e7 2007 goto fail;
97f82db3
KS
2008
2009 r = bus_remarshal_message(bus, &m);
2010 if (r < 0)
759e02e7 2011 goto fail;
97f82db3 2012
66baf8c6 2013 r = sd_bus_send(bus, m, &cookie);
de1c301e 2014 if (r < 0)
759e02e7 2015 goto fail;
de1c301e 2016
ac8029fc 2017 timeout = calc_elapse(bus, m->timeout);
de1c301e
LP
2018
2019 for (;;) {
2020 usec_t left;
de1c301e 2021
7d22c717
LP
2022 while (i < bus->rqueue_size) {
2023 sd_bus_message *incoming = NULL;
2024
2025 incoming = bus->rqueue[i];
89ffcd2a 2026
693eb9a2 2027 if (incoming->reply_cookie == cookie) {
de1c301e
LP
2028 /* Found a match! */
2029
7d22c717
LP
2030 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
2031 bus->rqueue_size--;
f9f97ca6 2032 log_debug_bus_message(incoming);
7d22c717 2033
40ca29a1 2034 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
b7f247e0 2035
c7db1984 2036 if (incoming->n_fds <= 0 || bus->accept_fd) {
2ce97e2b
LP
2037 if (reply)
2038 *reply = incoming;
2039 else
2040 sd_bus_message_unref(incoming);
2041
2042 return 1;
2043 }
2044
2045 r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
759e02e7
LP
2046 sd_bus_message_unref(incoming);
2047 return r;
b7f247e0 2048
759e02e7 2049 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) {
de1c301e 2050 r = sd_bus_error_copy(error, &incoming->error);
759e02e7
LP
2051 sd_bus_message_unref(incoming);
2052 return r;
2053 } else {
a43b9ca3 2054 r = -EIO;
759e02e7
LP
2055 goto fail;
2056 }
a8a07f89 2057
693eb9a2 2058 } else if (BUS_MESSAGE_COOKIE(incoming) == cookie &&
a8a07f89
LP
2059 bus->unique_name &&
2060 incoming->sender &&
2061 streq(bus->unique_name, incoming->sender)) {
2062
7d22c717
LP
2063 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
2064 bus->rqueue_size--;
2065
a8a07f89
LP
2066 /* Our own message? Somebody is trying
2067 * to send its own client a message,
2068 * let's not dead-lock, let's fail
2069 * immediately. */
2070
2071 sd_bus_message_unref(incoming);
759e02e7
LP
2072 r = -ELOOP;
2073 goto fail;
de1c301e
LP
2074 }
2075
de1c301e 2076 /* Try to read more, right-away */
7d22c717 2077 i++;
de1c301e 2078 }
7d22c717 2079
766c5809 2080 r = bus_read_message(bus, false, 0);
32f46480 2081 if (r < 0) {
103a5027 2082 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
32f46480 2083 bus_enter_closing(bus);
759e02e7 2084 r = -ECONNRESET;
441d56a1 2085 }
32f46480 2086
759e02e7 2087 goto fail;
32f46480 2088 }
7d22c717 2089 if (r > 0)
e3017af9 2090 continue;
de1c301e
LP
2091
2092 if (timeout > 0) {
2093 usec_t n;
2094
2095 n = now(CLOCK_MONOTONIC);
759e02e7
LP
2096 if (n >= timeout) {
2097 r = -ETIMEDOUT;
2098 goto fail;
2099 }
de1c301e
LP
2100
2101 left = timeout - n;
2102 } else
2103 left = (uint64_t) -1;
2104
e3017af9 2105 r = bus_poll(bus, true, left);
de1c301e 2106 if (r < 0)
759e02e7
LP
2107 goto fail;
2108 if (r == 0) {
2109 r = -ETIMEDOUT;
2110 goto fail;
2111 }
de1c301e
LP
2112
2113 r = dispatch_wqueue(bus);
32f46480 2114 if (r < 0) {
103a5027 2115 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
32f46480 2116 bus_enter_closing(bus);
759e02e7 2117 r = -ECONNRESET;
441d56a1 2118 }
32f46480 2119
759e02e7 2120 goto fail;
32f46480 2121 }
de1c301e 2122 }
759e02e7
LP
2123
2124fail:
2125 return sd_bus_error_set_errno(error, r);
de1c301e
LP
2126}
2127
d9f644e2 2128_public_ int sd_bus_get_fd(sd_bus *bus) {
d6888822
LP
2129
2130 assert_return(bus, -EINVAL);
d6888822
LP
2131 assert_return(bus->input_fd == bus->output_fd, -EPERM);
2132 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2133
8a5cd31e
LP
2134 if (bus->state == BUS_CLOSED)
2135 return -ENOTCONN;
2136
2137 if (bus->inotify_fd >= 0)
2138 return bus->inotify_fd;
2139
2140 if (bus->input_fd >= 0)
2141 return bus->input_fd;
2142
2143 return -ENOTCONN;
de1c301e
LP
2144}
2145
d9f644e2 2146_public_ int sd_bus_get_events(sd_bus *bus) {
de1c301e
LP
2147 int flags = 0;
2148
d6888822 2149 assert_return(bus, -EINVAL);
d6888822 2150 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2151
8a5cd31e
LP
2152 switch (bus->state) {
2153
2154 case BUS_UNSET:
2155 case BUS_CLOSED:
a3d59cd1
LP
2156 return -ENOTCONN;
2157
8a5cd31e
LP
2158 case BUS_WATCH_BIND:
2159 flags |= POLLIN;
2160 break;
2161
2162 case BUS_OPENING:
de1c301e 2163 flags |= POLLOUT;
8a5cd31e 2164 break;
89ffcd2a 2165
8a5cd31e 2166 case BUS_AUTHENTICATING:
2181a7f5 2167 if (bus_socket_auth_needs_write(bus))
89ffcd2a
LP
2168 flags |= POLLOUT;
2169
2170 flags |= POLLIN;
8a5cd31e 2171 break;
89ffcd2a 2172
8a5cd31e
LP
2173 case BUS_RUNNING:
2174 case BUS_HELLO:
de1c301e
LP
2175 if (bus->rqueue_size <= 0)
2176 flags |= POLLIN;
2177 if (bus->wqueue_size > 0)
2178 flags |= POLLOUT;
8a5cd31e
LP
2179 break;
2180
2181 case BUS_CLOSING:
2182 break;
2183
2184 default:
2185 assert_not_reached("Unknown state");
de1c301e
LP
2186 }
2187
2188 return flags;
2189}
2190
d9f644e2 2191_public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
e3017af9
LP
2192 struct reply_callback *c;
2193
d6888822
LP
2194 assert_return(bus, -EINVAL);
2195 assert_return(timeout_usec, -EINVAL);
d6888822 2196 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 2197
a3d59cd1
LP
2198 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
2199 return -ENOTCONN;
2200
8f8f05a9
LP
2201 if (bus->track_queue) {
2202 *timeout_usec = 0;
2203 return 1;
2204 }
2205
8a5cd31e 2206 switch (bus->state) {
718db961 2207
8a5cd31e 2208 case BUS_AUTHENTICATING:
e3017af9
LP
2209 *timeout_usec = bus->auth_timeout;
2210 return 1;
e3017af9 2211
8a5cd31e
LP
2212 case BUS_RUNNING:
2213 case BUS_HELLO:
2214 if (bus->rqueue_size > 0) {
2215 *timeout_usec = 0;
2216 return 1;
2217 }
2218
2219 c = prioq_peek(bus->reply_callbacks_prioq);
2220 if (!c) {
2221 *timeout_usec = (uint64_t) -1;
2222 return 0;
2223 }
2224
ac8029fc 2225 if (c->timeout_usec == 0) {
8a5cd31e
LP
2226 *timeout_usec = (uint64_t) -1;
2227 return 0;
2228 }
2229
ac8029fc 2230 *timeout_usec = c->timeout_usec;
8a5cd31e 2231 return 1;
e3017af9 2232
8a5cd31e 2233 case BUS_CLOSING:
8efd6381
LP
2234 *timeout_usec = 0;
2235 return 1;
8efd6381 2236
8a5cd31e
LP
2237 case BUS_WATCH_BIND:
2238 case BUS_OPENING:
adee69fa 2239 *timeout_usec = (uint64_t) -1;
e3017af9
LP
2240 return 0;
2241
8a5cd31e
LP
2242 default:
2243 assert_not_reached("Unknown or unexpected stat");
19befb2d 2244 }
e3017af9
LP
2245}
2246
2247static int process_timeout(sd_bus *bus) {
4afd3348
LP
2248 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2249 _cleanup_(sd_bus_message_unrefp) sd_bus_message* m = NULL;
e3017af9 2250 struct reply_callback *c;
1b64f838 2251 sd_bus_slot *slot;
b057498a 2252 bool is_hello;
e3017af9
LP
2253 usec_t n;
2254 int r;
2255
2256 assert(bus);
ac8029fc 2257 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
e3017af9
LP
2258
2259 c = prioq_peek(bus->reply_callbacks_prioq);
2260 if (!c)
2261 return 0;
2262
2263 n = now(CLOCK_MONOTONIC);
ac8029fc 2264 if (c->timeout_usec > n)
e3017af9
LP
2265 return 0;
2266
eb01ba5d
LP
2267 r = bus_message_new_synthetic_error(
2268 bus,
693eb9a2 2269 c->cookie,
14c24659 2270 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
eb01ba5d
LP
2271 &m);
2272 if (r < 0)
2273 return r;
2274
7adc46fc 2275 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2276 if (r < 0)
2277 return r;
2278
e3017af9 2279 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
ac8029fc 2280 c->timeout_usec = 0;
19befb2d 2281
c9fe4af7 2282 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
19befb2d
LP
2283 c->cookie = 0;
2284
1b64f838 2285 slot = container_of(c, sd_bus_slot, reply_callback);
e3017af9 2286
313cefa1 2287 bus->iteration_counter++;
718db961 2288
b057498a
LP
2289 is_hello = bus->state == BUS_HELLO && c->callback == hello_callback;
2290
1b64f838
LP
2291 bus->current_message = m;
2292 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2293 bus->current_handler = c->callback;
2294 bus->current_userdata = slot->userdata;
19070062 2295 r = c->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2296 bus->current_userdata = NULL;
2297 bus->current_handler = NULL;
d974ad05 2298 bus->current_slot = NULL;
19befb2d 2299 bus->current_message = NULL;
718db961 2300
1b64f838
LP
2301 if (slot->floating) {
2302 bus_slot_disconnect(slot);
2303 sd_bus_slot_unref(slot);
2304 }
2305
d974ad05
DH
2306 sd_bus_slot_unref(slot);
2307
8a5cd31e
LP
2308 /* When this is the hello message and it timed out, then make sure to propagate the error up, don't just log
2309 * and ignore the callback handler's return value. */
b057498a
LP
2310 if (is_hello)
2311 return r;
2312
1b64f838 2313 return bus_maybe_reply_error(m, r, &error_buffer);
e3017af9
LP
2314}
2315
9d373862
LP
2316static int process_hello(sd_bus *bus, sd_bus_message *m) {
2317 assert(bus);
2318 assert(m);
2319
2320 if (bus->state != BUS_HELLO)
2321 return 0;
2322
2323 /* Let's make sure the first message on the bus is the HELLO
2324 * reply. But note that we don't actually parse the message
2181a7f5
LP
2325 * here (we leave that to the usual handling), we just verify
2326 * we don't let any earlier msg through. */
9d373862 2327
945c2931 2328 if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
9d373862
LP
2329 return -EIO;
2330
19befb2d 2331 if (m->reply_cookie != 1)
9d373862
LP
2332 return -EIO;
2333
2334 return 0;
2335}
2336
a652755d 2337static int process_reply(sd_bus *bus, sd_bus_message *m) {
4afd3348
LP
2338 _cleanup_(sd_bus_message_unrefp) sd_bus_message *synthetic_reply = NULL;
2339 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
19befb2d 2340 struct reply_callback *c;
1b64f838 2341 sd_bus_slot *slot;
b057498a 2342 bool is_hello;
a652755d
LP
2343 int r;
2344
2345 assert(bus);
2346 assert(m);
2347
945c2931 2348 if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
a652755d
LP
2349 return 0;
2350
09365592
LP
2351 if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
2352 return 0;
2353
c9fe4af7 2354 c = ordered_hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
a652755d
LP
2355 if (!c)
2356 return 0;
2357
19befb2d 2358 c->cookie = 0;
19befb2d 2359
1b64f838 2360 slot = container_of(c, sd_bus_slot, reply_callback);
a652755d 2361
c7db1984 2362 if (m->n_fds > 0 && !bus->accept_fd) {
2ce97e2b
LP
2363
2364 /* If the reply contained a file descriptor which we
2365 * didn't want we pass an error instead. */
2366
2367 r = bus_message_new_synthetic_error(
2368 bus,
2369 m->reply_cookie,
2370 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptor"),
2371 &synthetic_reply);
2372 if (r < 0)
1b64f838 2373 return r;
2ce97e2b 2374
52cd5877
LP
2375 /* Copy over original timestamp */
2376 synthetic_reply->realtime = m->realtime;
2377 synthetic_reply->monotonic = m->monotonic;
2378 synthetic_reply->seqnum = m->seqnum;
2379
2ce97e2b
LP
2380 r = bus_seal_synthetic_message(bus, synthetic_reply);
2381 if (r < 0)
1b64f838 2382 return r;
2ce97e2b
LP
2383
2384 m = synthetic_reply;
2385 } else {
2386 r = sd_bus_message_rewind(m, true);
2387 if (r < 0)
1b64f838 2388 return r;
2ce97e2b 2389 }
88fe224c 2390
ac8029fc 2391 if (c->timeout_usec != 0) {
1b64f838 2392 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
ac8029fc 2393 c->timeout_usec = 0;
1b64f838 2394 }
19befb2d 2395
b057498a
LP
2396 is_hello = bus->state == BUS_HELLO && c->callback == hello_callback;
2397
1b64f838 2398 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2399 bus->current_handler = c->callback;
2400 bus->current_userdata = slot->userdata;
19070062 2401 r = c->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2402 bus->current_userdata = NULL;
2403 bus->current_handler = NULL;
d974ad05 2404 bus->current_slot = NULL;
a652755d 2405
19befb2d
LP
2406 if (slot->floating) {
2407 bus_slot_disconnect(slot);
2408 sd_bus_slot_unref(slot);
2409 }
2410
d974ad05
DH
2411 sd_bus_slot_unref(slot);
2412
8a5cd31e
LP
2413 /* When this is the hello message and it failed, then make sure to propagate the error up, don't just log and
2414 * ignore the callback handler's return value. */
b057498a
LP
2415 if (is_hello)
2416 return r;
2417
1b64f838 2418 return bus_maybe_reply_error(m, r, &error_buffer);
a652755d
LP
2419}
2420
2421static int process_filter(sd_bus *bus, sd_bus_message *m) {
4afd3348 2422 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
a652755d
LP
2423 struct filter_callback *l;
2424 int r;
2425
392d5b37
LP
2426 assert(bus);
2427 assert(m);
2428
7286037f
LP
2429 do {
2430 bus->filter_callbacks_modified = false;
2431
2432 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
1b64f838 2433 sd_bus_slot *slot;
7286037f
LP
2434
2435 if (bus->filter_callbacks_modified)
2436 break;
2437
2438 /* Don't run this more than once per iteration */
2439 if (l->last_iteration == bus->iteration_counter)
2440 continue;
2441
2442 l->last_iteration = bus->iteration_counter;
2443
88fe224c
LP
2444 r = sd_bus_message_rewind(m, true);
2445 if (r < 0)
2446 return r;
2447
1b64f838
LP
2448 slot = container_of(l, sd_bus_slot, filter_callback);
2449
2450 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2451 bus->current_handler = l->callback;
2452 bus->current_userdata = slot->userdata;
19070062 2453 r = l->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2454 bus->current_userdata = NULL;
2455 bus->current_handler = NULL;
1b64f838 2456 bus->current_slot = sd_bus_slot_unref(slot);
19befb2d 2457
ebcf1f97 2458 r = bus_maybe_reply_error(m, r, &error_buffer);
7286037f
LP
2459 if (r != 0)
2460 return r;
2461
2462 }
2463
2464 } while (bus->filter_callbacks_modified);
a652755d
LP
2465
2466 return 0;
2467}
2468
392d5b37 2469static int process_match(sd_bus *bus, sd_bus_message *m) {
7286037f
LP
2470 int r;
2471
392d5b37
LP
2472 assert(bus);
2473 assert(m);
2474
7286037f
LP
2475 do {
2476 bus->match_callbacks_modified = false;
2477
eb01ba5d 2478 r = bus_match_run(bus, &bus->match_callbacks, m);
7286037f
LP
2479 if (r != 0)
2480 return r;
2481
2482 } while (bus->match_callbacks_modified);
2483
2484 return 0;
392d5b37
LP
2485}
2486
b9bf7e2b 2487static int process_builtin(sd_bus *bus, sd_bus_message *m) {
4afd3348 2488 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
b9bf7e2b
LP
2489 int r;
2490
2491 assert(bus);
2492 assert(m);
2493
c7db1984 2494 if (bus->is_monitor)
09365592
LP
2495 return 0;
2496
758bf0c7
LP
2497 if (bus->manual_peer_interface)
2498 return 0;
2499
40ca29a1 2500 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
b9bf7e2b
LP
2501 return 0;
2502
2503 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
2504 return 0;
2505
0461f8cd 2506 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
b9bf7e2b
LP
2507 return 1;
2508
2509 if (streq_ptr(m->member, "Ping"))
df2d202e 2510 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2511 else if (streq_ptr(m->member, "GetMachineId")) {
2512 sd_id128_t id;
2513 char sid[33];
2514
2515 r = sd_id128_get_machine(&id);
2516 if (r < 0)
2517 return r;
2518
df2d202e 2519 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2520 if (r < 0)
2521 return r;
2522
2523 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
2524 } else {
29ddb38f 2525 r = sd_bus_message_new_method_errorf(
df2d202e 2526 m, &reply,
40ca29a1 2527 SD_BUS_ERROR_UNKNOWN_METHOD,
b9bf7e2b 2528 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
b9bf7e2b
LP
2529 }
2530
2531 if (r < 0)
2532 return r;
2533
2534 r = sd_bus_send(bus, reply, NULL);
2535 if (r < 0)
2536 return r;
2537
2538 return 1;
2539}
2540
2ce97e2b
LP
2541static int process_fd_check(sd_bus *bus, sd_bus_message *m) {
2542 assert(bus);
2543 assert(m);
2544
2545 /* If we got a message with a file descriptor which we didn't
2546 * want to accept, then let's drop it. How can this even
2547 * happen? For example, when the kernel queues a message into
2548 * an activatable names's queue which allows fds, and then is
2549 * delivered to us later even though we ourselves did not
2550 * negotiate it. */
2551
c7db1984 2552 if (bus->is_monitor)
09365592
LP
2553 return 0;
2554
2ce97e2b
LP
2555 if (m->n_fds <= 0)
2556 return 0;
2557
c7db1984 2558 if (bus->accept_fd)
2ce97e2b
LP
2559 return 0;
2560
2561 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
2562 return 1; /* just eat it up */
2563
2564 return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Message contains file descriptors, which I cannot accept. Sorry.");
2565}
2566
992c052c 2567static int process_message(sd_bus *bus, sd_bus_message *m) {
e3017af9
LP
2568 int r;
2569
2570 assert(bus);
992c052c 2571 assert(m);
e3017af9 2572
19befb2d 2573 bus->current_message = m;
992c052c 2574 bus->iteration_counter++;
e3017af9 2575
f9f97ca6 2576 log_debug_bus_message(m);
40ca29a1 2577
992c052c
LP
2578 r = process_hello(bus, m);
2579 if (r != 0)
affff0b6 2580 goto finish;
a652755d 2581
992c052c
LP
2582 r = process_reply(bus, m);
2583 if (r != 0)
affff0b6 2584 goto finish;
e3017af9 2585
2ce97e2b
LP
2586 r = process_fd_check(bus, m);
2587 if (r != 0)
2588 goto finish;
2589
992c052c
LP
2590 r = process_filter(bus, m);
2591 if (r != 0)
affff0b6 2592 goto finish;
a652755d 2593
992c052c
LP
2594 r = process_match(bus, m);
2595 if (r != 0)
affff0b6 2596 goto finish;
a652755d 2597
992c052c
LP
2598 r = process_builtin(bus, m);
2599 if (r != 0)
affff0b6
LP
2600 goto finish;
2601
2602 r = bus_process_object(bus, m);
a652755d 2603
affff0b6 2604finish:
19befb2d 2605 bus->current_message = NULL;
affff0b6 2606 return r;
29ddb38f 2607}
88fe224c 2608
8f8f05a9
LP
2609static int dispatch_track(sd_bus *bus) {
2610 assert(bus);
2611
2612 if (!bus->track_queue)
2613 return 0;
2614
2615 bus_track_dispatch(bus->track_queue);
2616 return 1;
2617}
2618
766c5809 2619static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
4afd3348 2620 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
29ddb38f 2621 int r;
a652755d 2622
29ddb38f 2623 assert(bus);
945c2931 2624 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
7286037f 2625
992c052c
LP
2626 r = process_timeout(bus);
2627 if (r != 0)
2628 goto null_message;
7286037f 2629
992c052c
LP
2630 r = dispatch_wqueue(bus);
2631 if (r != 0)
2632 goto null_message;
7286037f 2633
8f8f05a9
LP
2634 r = dispatch_track(bus);
2635 if (r != 0)
2636 goto null_message;
2637
766c5809 2638 r = dispatch_rqueue(bus, hint_priority, priority, &m);
992c052c
LP
2639 if (r < 0)
2640 return r;
2641 if (!m)
2642 goto null_message;
7286037f 2643
992c052c
LP
2644 r = process_message(bus, m);
2645 if (r != 0)
2646 goto null_message;
7286037f 2647
992c052c
LP
2648 if (ret) {
2649 r = sd_bus_message_rewind(m, true);
29ddb38f
LP
2650 if (r < 0)
2651 return r;
e3017af9 2652
992c052c
LP
2653 *ret = m;
2654 m = NULL;
2655 return 1;
2656 }
a652755d 2657
40ca29a1 2658 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
a652755d 2659
dc74ce9b
LP
2660 log_debug("Unprocessed message call sender=%s object=%s interface=%s member=%s",
2661 strna(sd_bus_message_get_sender(m)),
2662 strna(sd_bus_message_get_path(m)),
2663 strna(sd_bus_message_get_interface(m)),
2664 strna(sd_bus_message_get_member(m)));
2665
992c052c 2666 r = sd_bus_reply_method_errorf(
df2d202e 2667 m,
40ca29a1 2668 SD_BUS_ERROR_UNKNOWN_OBJECT,
992c052c 2669 "Unknown object '%s'.", m->path);
29ddb38f
LP
2670 if (r < 0)
2671 return r;
2672 }
e3017af9 2673
992c052c 2674 return 1;
0a72c2bd 2675
992c052c
LP
2676null_message:
2677 if (r >= 0 && ret)
2678 *ret = NULL;
0a72c2bd 2679
992c052c 2680 return r;
29ddb38f 2681}
0a72c2bd 2682
fbb4603d
LP
2683static int bus_exit_now(sd_bus *bus) {
2684 assert(bus);
2685
2686 /* Exit due to close, if this is requested. If this is bus object is attached to an event source, invokes
2687 * sd_event_exit(), otherwise invokes libc exit(). */
2688
2689 if (bus->exited) /* did we already exit? */
2690 return 0;
2691 if (!bus->exit_triggered) /* was the exit condition triggered? */
2692 return 0;
2693 if (!bus->exit_on_disconnect) /* Shall we actually exit on disconnection? */
2694 return 0;
2695
2696 bus->exited = true; /* never exit more than once */
2697
2698 log_debug("Bus connection disconnected, exiting.");
2699
2700 if (bus->event)
2701 return sd_event_exit(bus->event, EXIT_FAILURE);
2702 else
2703 exit(EXIT_FAILURE);
2704
2705 assert_not_reached("exit() didn't exit?");
2706}
2707
217fcc7e
LP
2708static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) {
2709 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
4afd3348 2710 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
217fcc7e 2711 sd_bus_slot *slot;
718db961
LP
2712 int r;
2713
2714 assert(bus);
217fcc7e 2715 assert(c);
718db961 2716
217fcc7e
LP
2717 r = bus_message_new_synthetic_error(
2718 bus,
2719 c->cookie,
2720 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
2721 &m);
2722 if (r < 0)
2723 return r;
ebcf1f97 2724
217fcc7e
LP
2725 r = bus_seal_synthetic_message(bus, m);
2726 if (r < 0)
2727 return r;
718db961 2728
ac8029fc 2729 if (c->timeout_usec != 0) {
217fcc7e 2730 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
ac8029fc 2731 c->timeout_usec = 0;
217fcc7e 2732 }
718db961 2733
217fcc7e
LP
2734 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
2735 c->cookie = 0;
2736
2737 slot = container_of(c, sd_bus_slot, reply_callback);
718db961 2738
217fcc7e 2739 bus->iteration_counter++;
19befb2d 2740
217fcc7e
LP
2741 bus->current_message = m;
2742 bus->current_slot = sd_bus_slot_ref(slot);
2743 bus->current_handler = c->callback;
2744 bus->current_userdata = slot->userdata;
2745 r = c->callback(m, slot->userdata, &error_buffer);
2746 bus->current_userdata = NULL;
2747 bus->current_handler = NULL;
2748 bus->current_slot = NULL;
2749 bus->current_message = NULL;
718db961 2750
217fcc7e
LP
2751 if (slot->floating) {
2752 bus_slot_disconnect(slot);
2753 sd_bus_slot_unref(slot);
2754 }
718db961 2755
217fcc7e 2756 sd_bus_slot_unref(slot);
1b64f838 2757
217fcc7e
LP
2758 return bus_maybe_reply_error(m, r, &error_buffer);
2759}
718db961 2760
217fcc7e
LP
2761static int process_closing(sd_bus *bus, sd_bus_message **ret) {
2762 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2763 struct reply_callback *c;
2764 int r;
d974ad05 2765
217fcc7e
LP
2766 assert(bus);
2767 assert(bus->state == BUS_CLOSING);
2768
2769 /* First, fail all outstanding method calls */
2770 c = ordered_hashmap_first(bus->reply_callbacks);
2771 if (c)
2772 return process_closing_reply_callback(bus, c);
718db961 2773
232f3677
LP
2774 /* Then, fake-drop all remaining bus tracking references */
2775 if (bus->tracks) {
2776 bus_track_close(bus->tracks);
2777 return 1;
2778 }
2779
718db961
LP
2780 /* Then, synthesize a Disconnected message */
2781 r = sd_bus_message_new_signal(
2782 bus,
151b9b96 2783 &m,
718db961
LP
2784 "/org/freedesktop/DBus/Local",
2785 "org.freedesktop.DBus.Local",
151b9b96 2786 "Disconnected");
718db961
LP
2787 if (r < 0)
2788 return r;
2789
fb6d9b77 2790 bus_message_set_sender_local(bus, m);
34a2c9e8 2791
7adc46fc 2792 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2793 if (r < 0)
2794 return r;
2795
2796 sd_bus_close(bus);
2797
19befb2d 2798 bus->current_message = m;
718db961
LP
2799 bus->iteration_counter++;
2800
2801 r = process_filter(bus, m);
2802 if (r != 0)
2803 goto finish;
2804
2805 r = process_match(bus, m);
2806 if (r != 0)
2807 goto finish;
2808
fbb4603d
LP
2809 /* Nothing else to do, exit now, if the condition holds */
2810 bus->exit_triggered = true;
2811 (void) bus_exit_now(bus);
2812
718db961
LP
2813 if (ret) {
2814 *ret = m;
2815 m = NULL;
2816 }
2817
2818 r = 1;
2819
2820finish:
19befb2d
LP
2821 bus->current_message = NULL;
2822
718db961
LP
2823 return r;
2824}
2825
766c5809 2826static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
8ce2afd6 2827 BUS_DONT_DESTROY(bus);
29ddb38f 2828 int r;
0a72c2bd 2829
992c052c
LP
2830 /* Returns 0 when we didn't do anything. This should cause the
2831 * caller to invoke sd_bus_wait() before returning the next
2832 * time. Returns > 0 when we did something, which possibly
2833 * means *ret is filled in with an unprocessed message. */
0a72c2bd 2834
d6888822
LP
2835 assert_return(bus, -EINVAL);
2836 assert_return(!bus_pid_changed(bus), -ECHILD);
0a72c2bd 2837
992c052c 2838 /* We don't allow recursively invoking sd_bus_process(). */
19befb2d
LP
2839 assert_return(!bus->current_message, -EBUSY);
2840 assert(!bus->current_slot);
0a72c2bd 2841
992c052c 2842 switch (bus->state) {
0a72c2bd 2843
992c052c 2844 case BUS_UNSET:
992c052c 2845 return -ENOTCONN;
0a72c2bd 2846
6d6f4904
LP
2847 case BUS_CLOSED:
2848 return -ECONNRESET;
2849
8a5cd31e
LP
2850 case BUS_WATCH_BIND:
2851 r = bus_socket_process_watch_bind(bus);
2852 break;
2853
992c052c
LP
2854 case BUS_OPENING:
2855 r = bus_socket_process_opening(bus);
8a5cd31e 2856 break;
a652755d 2857
992c052c 2858 case BUS_AUTHENTICATING:
992c052c 2859 r = bus_socket_process_authenticating(bus);
8a5cd31e 2860 break;
a652755d 2861
992c052c
LP
2862 case BUS_RUNNING:
2863 case BUS_HELLO:
766c5809 2864 r = process_running(bus, hint_priority, priority, ret);
8a5cd31e
LP
2865 if (r >= 0)
2866 return r;
718db961 2867
8a5cd31e
LP
2868 /* This branch initializes *ret, hence we don't use the generic error checking below */
2869 break;
718db961
LP
2870
2871 case BUS_CLOSING:
2872 return process_closing(bus, ret);
8a5cd31e
LP
2873
2874 default:
2875 assert_not_reached("Unknown state");
992c052c 2876 }
43a43f50 2877
8a5cd31e
LP
2878 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2879 bus_enter_closing(bus);
2880 r = 1;
2881 } else if (r < 0)
2882 return r;
2883
2884 if (ret)
2885 *ret = NULL;
2886
2887 return r;
e3017af9
LP
2888}
2889
766c5809
LP
2890_public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
2891 return bus_process_internal(bus, false, 0, ret);
2892}
2893
2894_public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) {
2895 return bus_process_internal(bus, true, priority, ret);
2896}
2897
992c052c
LP
2898static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2899 struct pollfd p[2] = {};
8a5cd31e 2900 int r, n;
992c052c 2901 struct timespec ts;
3a43da28 2902 usec_t m = USEC_INFINITY;
adcdb374
LP
2903
2904 assert(bus);
718db961
LP
2905
2906 if (bus->state == BUS_CLOSING)
2907 return 1;
2908
a3d59cd1
LP
2909 if (!BUS_IS_OPEN(bus->state))
2910 return -ENOTCONN;
adcdb374 2911
8a5cd31e
LP
2912 if (bus->state == BUS_WATCH_BIND) {
2913 assert(bus->inotify_fd >= 0);
adcdb374 2914
8a5cd31e
LP
2915 p[0].events = POLLIN;
2916 p[0].fd = bus->inotify_fd;
992c052c
LP
2917 n = 1;
2918 } else {
8a5cd31e
LP
2919 int e;
2920
2921 e = sd_bus_get_events(bus);
2922 if (e < 0)
2923 return e;
2924
2925 if (need_more)
2926 /* The caller really needs some more data, he doesn't
2927 * care about what's already read, or any timeouts
2928 * except its own. */
2929 e |= POLLIN;
2930 else {
2931 usec_t until;
2932 /* The caller wants to process if there's something to
2933 * process, but doesn't care otherwise */
2934
2935 r = sd_bus_get_timeout(bus, &until);
2936 if (r < 0)
2937 return r;
2938 if (r > 0)
2939 m = usec_sub_unsigned(until, now(CLOCK_MONOTONIC));
2940 }
2941
2942 p[0].fd = bus->input_fd;
2943 if (bus->output_fd == bus->input_fd) {
2944 p[0].events = e;
2945 n = 1;
2946 } else {
2947 p[0].events = e & POLLIN;
2948 p[1].fd = bus->output_fd;
2949 p[1].events = e & POLLOUT;
2950 n = 2;
2951 }
adcdb374
LP
2952 }
2953
8a5cd31e
LP
2954 if (timeout_usec != (uint64_t) -1 && (m == USEC_INFINITY || timeout_usec < m))
2955 m = timeout_usec;
2956
2957 r = ppoll(p, n, m == USEC_INFINITY ? NULL : timespec_store(&ts, m), NULL);
adcdb374 2958 if (r < 0)
992c052c 2959 return -errno;
adcdb374 2960
992c052c 2961 return r > 0 ? 1 : 0;
adcdb374
LP
2962}
2963
d9f644e2 2964_public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
9db76355 2965
d6888822 2966 assert_return(bus, -EINVAL);
d6888822 2967 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2968
718db961
LP
2969 if (bus->state == BUS_CLOSING)
2970 return 0;
2971
a3d59cd1
LP
2972 if (!BUS_IS_OPEN(bus->state))
2973 return -ENOTCONN;
718db961 2974
992c052c
LP
2975 if (bus->rqueue_size > 0)
2976 return 0;
9db76355 2977
992c052c
LP
2978 return bus_poll(bus, false, timeout_usec);
2979}
9db76355 2980
d9f644e2 2981_public_ int sd_bus_flush(sd_bus *bus) {
992c052c 2982 int r;
9db76355 2983
d6888822 2984 assert_return(bus, -EINVAL);
d6888822 2985 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2986
718db961
LP
2987 if (bus->state == BUS_CLOSING)
2988 return 0;
2989
a3d59cd1
LP
2990 if (!BUS_IS_OPEN(bus->state))
2991 return -ENOTCONN;
718db961 2992
8a5cd31e
LP
2993 /* We never were connected? Don't hang in inotify for good, as there's no timeout set for it */
2994 if (bus->state == BUS_WATCH_BIND)
2995 return -EUNATCH;
2996
992c052c
LP
2997 r = bus_ensure_running(bus);
2998 if (r < 0)
2999 return r;
9db76355 3000
992c052c
LP
3001 if (bus->wqueue_size <= 0)
3002 return 0;
9db76355 3003
992c052c
LP
3004 for (;;) {
3005 r = dispatch_wqueue(bus);
32f46480 3006 if (r < 0) {
103a5027 3007 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
32f46480 3008 bus_enter_closing(bus);
441d56a1
LP
3009 return -ECONNRESET;
3010 }
32f46480 3011
9db76355 3012 return r;
32f46480 3013 }
9db76355 3014
992c052c
LP
3015 if (bus->wqueue_size <= 0)
3016 return 0;
9db76355 3017
992c052c 3018 r = bus_poll(bus, false, (uint64_t) -1);
9db76355
LP
3019 if (r < 0)
3020 return r;
9db76355 3021 }
9db76355
LP
3022}
3023
19befb2d
LP
3024_public_ int sd_bus_add_filter(
3025 sd_bus *bus,
3026 sd_bus_slot **slot,
3027 sd_bus_message_handler_t callback,
3028 void *userdata) {
d9f644e2 3029
19befb2d 3030 sd_bus_slot *s;
de1c301e 3031
d6888822
LP
3032 assert_return(bus, -EINVAL);
3033 assert_return(callback, -EINVAL);
3034 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 3035
19befb2d
LP
3036 s = bus_slot_allocate(bus, !slot, BUS_FILTER_CALLBACK, sizeof(struct filter_callback), userdata);
3037 if (!s)
29ddb38f
LP
3038 return -ENOMEM;
3039
19befb2d 3040 s->filter_callback.callback = callback;
a652755d 3041
19befb2d
LP
3042 bus->filter_callbacks_modified = true;
3043 LIST_PREPEND(callbacks, bus->filter_callbacks, &s->filter_callback);
a652755d 3044
19befb2d
LP
3045 if (slot)
3046 *slot = s;
29ddb38f 3047
992c052c 3048 return 0;
a652755d 3049}
392d5b37 3050
7593c7a4
LP
3051static int add_match_callback(
3052 sd_bus_message *m,
3053 void *userdata,
3054 sd_bus_error *ret_error) {
3055
3056 sd_bus_slot *match_slot = userdata;
3057 bool failed = false;
3058 int r;
3059
3060 assert(m);
3061 assert(match_slot);
3062
3063 sd_bus_slot_ref(match_slot);
3064
3065 if (sd_bus_message_is_method_error(m, NULL)) {
3066 log_debug_errno(sd_bus_message_get_errno(m),
3067 "Unable to add match %s, failing connection: %s",
3068 match_slot->match_callback.match_string,
3069 sd_bus_message_get_error(m)->message);
3070
3071 failed = true;
3072 } else
3073 log_debug("Match %s successfully installed.", match_slot->match_callback.match_string);
3074
3075 if (match_slot->match_callback.install_callback) {
3076 sd_bus *bus;
3077
3078 bus = sd_bus_message_get_bus(m);
3079
3080 /* This function has been called as slot handler, and we want to call another slot handler. Let's
3081 * update the slot callback metadata temporarily with our own data, and then revert back to the old
3082 * values. */
3083
3084 assert(bus->current_slot == match_slot->match_callback.install_slot);
3085 assert(bus->current_handler == add_match_callback);
3086 assert(bus->current_userdata == userdata);
3087
3088 bus->current_slot = match_slot;
3089 bus->current_handler = match_slot->match_callback.install_callback;
3090 bus->current_userdata = match_slot->userdata;
3091
3092 r = match_slot->match_callback.install_callback(m, match_slot->userdata, ret_error);
3093
3094 bus->current_slot = match_slot->match_callback.install_slot;
3095 bus->current_handler = add_match_callback;
3096 bus->current_userdata = userdata;
3097
3098 match_slot->match_callback.install_slot = sd_bus_slot_unref(match_slot->match_callback.install_slot);
3099 } else {
3100 if (failed) /* Generic failure handling: destroy the connection */
3101 bus_enter_closing(sd_bus_message_get_bus(m));
3102
3103 r = 1;
3104 }
3105
3106 if (failed && match_slot->floating) {
3107 bus_slot_disconnect(match_slot);
3108 sd_bus_slot_unref(match_slot);
3109 }
3110
3111 sd_bus_slot_unref(match_slot);
3112
3113 return r;
3114}
3115
3116static int bus_add_match_full(
19befb2d
LP
3117 sd_bus *bus,
3118 sd_bus_slot **slot,
7593c7a4 3119 bool asynchronous,
19befb2d
LP
3120 const char *match,
3121 sd_bus_message_handler_t callback,
7593c7a4 3122 sd_bus_message_handler_t install_callback,
19befb2d 3123 void *userdata) {
d9f644e2 3124
992c052c
LP
3125 struct bus_match_component *components = NULL;
3126 unsigned n_components = 0;
2915234d 3127 sd_bus_slot *s = NULL;
992c052c 3128 int r = 0;
392d5b37 3129
d6888822
LP
3130 assert_return(bus, -EINVAL);
3131 assert_return(match, -EINVAL);
3132 assert_return(!bus_pid_changed(bus), -ECHILD);
392d5b37 3133
992c052c
LP
3134 r = bus_match_parse(match, &components, &n_components);
3135 if (r < 0)
3136 goto finish;
29ddb38f 3137
19befb2d
LP
3138 s = bus_slot_allocate(bus, !slot, BUS_MATCH_CALLBACK, sizeof(struct match_callback), userdata);
3139 if (!s) {
3140 r = -ENOMEM;
3141 goto finish;
3142 }
3143
3144 s->match_callback.callback = callback;
7593c7a4 3145 s->match_callback.install_callback = install_callback;
19befb2d 3146
992c052c 3147 if (bus->bus_client) {
cc65fe5e 3148 enum bus_match_scope scope;
29ddb38f 3149
cc65fe5e 3150 scope = bus_match_get_scope(components, n_components);
19befb2d 3151
7593c7a4 3152 /* Do not install server-side matches for matches against the local service, interface or bus path. */
9ee7a50c 3153 if (scope != BUS_MATCH_LOCAL) {
cc65fe5e 3154
7593c7a4 3155 /* We store the original match string, so that we can use it to remove the match again. */
cc65fe5e 3156
a132bef0
ZJS
3157 s->match_callback.match_string = strdup(match);
3158 if (!s->match_callback.match_string) {
3159 r = -ENOMEM;
3160 goto finish;
19befb2d 3161 }
19befb2d 3162
7593c7a4
LP
3163 if (asynchronous)
3164 r = bus_add_match_internal_async(bus,
3165 &s->match_callback.install_slot,
3166 s->match_callback.match_string,
3167 add_match_callback,
3168 s);
3169 else
3170 r = bus_add_match_internal(bus, s->match_callback.match_string);
cc65fe5e
LP
3171 if (r < 0)
3172 goto finish;
3173
3174 s->match_added = true;
3175 }
392d5b37
LP
3176 }
3177
992c052c 3178 bus->match_callbacks_modified = true;
19befb2d
LP
3179 r = bus_match_add(&bus->match_callbacks, components, n_components, &s->match_callback);
3180 if (r < 0)
3181 goto finish;
3182
3183 if (slot)
3184 *slot = s;
3185 s = NULL;
917b5dc7 3186
992c052c
LP
3187finish:
3188 bus_match_parse_free(components, n_components);
19befb2d
LP
3189 sd_bus_slot_unref(s);
3190
992c052c 3191 return r;
917b5dc7
LP
3192}
3193
7593c7a4
LP
3194_public_ int sd_bus_add_match(
3195 sd_bus *bus,
3196 sd_bus_slot **slot,
3197 const char *match,
3198 sd_bus_message_handler_t callback,
3199 void *userdata) {
3200
3201 return bus_add_match_full(bus, slot, false, match, callback, NULL, userdata);
3202}
3203
3204_public_ int sd_bus_add_match_async(
3205 sd_bus *bus,
3206 sd_bus_slot **slot,
3207 const char *match,
3208 sd_bus_message_handler_t callback,
3209 sd_bus_message_handler_t install_callback,
3210 void *userdata) {
3211
3212 return bus_add_match_full(bus, slot, true, match, callback, install_callback, userdata);
3213}
3214
992c052c
LP
3215bool bus_pid_changed(sd_bus *bus) {
3216 assert(bus);
f10dda3b 3217
992c052c
LP
3218 /* We don't support people creating a bus connection and
3219 * keeping it around over a fork(). Let's complain. */
d5a2b9a6 3220
df0ff127 3221 return bus->original_pid != getpid_cached();
d5a2b9a6 3222}
40ca29a1
LP
3223
3224static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
0927756b 3225 sd_bus *bus = userdata;
40ca29a1
LP
3226 int r;
3227
3228 assert(bus);
3229
8a5cd31e
LP
3230 /* Note that this is called both on input_fd, output_fd as well as inotify_fd events */
3231
40ca29a1 3232 r = sd_bus_process(bus, NULL);
5ae37ad8
LP
3233 if (r < 0) {
3234 log_debug_errno(r, "Processing of bus failed, closing down: %m");
3235 bus_enter_closing(bus);
3236 }
40ca29a1
LP
3237
3238 return 1;
3239}
3240
3241static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
0927756b 3242 sd_bus *bus = userdata;
40ca29a1
LP
3243 int r;
3244
3245 assert(bus);
3246
3247 r = sd_bus_process(bus, NULL);
5ae37ad8
LP
3248 if (r < 0) {
3249 log_debug_errno(r, "Processing of bus failed, closing down: %m");
3250 bus_enter_closing(bus);
3251 }
40ca29a1
LP
3252
3253 return 1;
3254}
3255
3256static int prepare_callback(sd_event_source *s, void *userdata) {
3257 sd_bus *bus = userdata;
3258 int r, e;
3259 usec_t until;
3260
3261 assert(s);
3262 assert(bus);
3263
3264 e = sd_bus_get_events(bus);
5ae37ad8
LP
3265 if (e < 0) {
3266 r = e;
3267 goto fail;
3268 }
40ca29a1
LP
3269
3270 if (bus->output_fd != bus->input_fd) {
3271
3272 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
3273 if (r < 0)
5ae37ad8 3274 goto fail;
40ca29a1
LP
3275
3276 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
5ae37ad8 3277 } else
40ca29a1 3278 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
5ae37ad8
LP
3279 if (r < 0)
3280 goto fail;
40ca29a1
LP
3281
3282 r = sd_bus_get_timeout(bus, &until);
3283 if (r < 0)
5ae37ad8 3284 goto fail;
40ca29a1
LP
3285 if (r > 0) {
3286 int j;
3287
3288 j = sd_event_source_set_time(bus->time_event_source, until);
5ae37ad8
LP
3289 if (j < 0) {
3290 r = j;
3291 goto fail;
3292 }
40ca29a1
LP
3293 }
3294
3295 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
3296 if (r < 0)
5ae37ad8
LP
3297 goto fail;
3298
3299 return 1;
3300
3301fail:
3302 log_debug_errno(r, "Preparing of bus events failed, closing down: %m");
3303 bus_enter_closing(bus);
40ca29a1
LP
3304
3305 return 1;
3306}
3307
abc5fe72
LP
3308static int quit_callback(sd_event_source *event, void *userdata) {
3309 sd_bus *bus = userdata;
3310
3311 assert(event);
3312
3313 sd_bus_flush(bus);
7bb4d371 3314 sd_bus_close(bus);
abc5fe72
LP
3315
3316 return 1;
3317}
3318
8a5cd31e 3319int bus_attach_io_events(sd_bus *bus) {
1e05d493
LP
3320 int r;
3321
3322 assert(bus);
3323
3324 if (bus->input_fd < 0)
3325 return 0;
3326
3327 if (!bus->event)
3328 return 0;
3329
3330 if (!bus->input_io_event_source) {
151b9b96 3331 r = sd_event_add_io(bus->event, &bus->input_io_event_source, bus->input_fd, 0, io_callback, bus);
1e05d493
LP
3332 if (r < 0)
3333 return r;
3334
3335 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
3336 if (r < 0)
3337 return r;
3338
3339 r = sd_event_source_set_priority(bus->input_io_event_source, bus->event_priority);
9021bb9f
TG
3340 if (r < 0)
3341 return r;
3342
356779df 3343 r = sd_event_source_set_description(bus->input_io_event_source, "bus-input");
1e05d493
LP
3344 } else
3345 r = sd_event_source_set_io_fd(bus->input_io_event_source, bus->input_fd);
3346
3347 if (r < 0)
3348 return r;
3349
3350 if (bus->output_fd != bus->input_fd) {
3351 assert(bus->output_fd >= 0);
3352
3353 if (!bus->output_io_event_source) {
151b9b96 3354 r = sd_event_add_io(bus->event, &bus->output_io_event_source, bus->output_fd, 0, io_callback, bus);
1e05d493
LP
3355 if (r < 0)
3356 return r;
3357
3358 r = sd_event_source_set_priority(bus->output_io_event_source, bus->event_priority);
9021bb9f
TG
3359 if (r < 0)
3360 return r;
3361
356779df 3362 r = sd_event_source_set_description(bus->input_io_event_source, "bus-output");
1e05d493
LP
3363 } else
3364 r = sd_event_source_set_io_fd(bus->output_io_event_source, bus->output_fd);
3365
3366 if (r < 0)
3367 return r;
3368 }
3369
3370 return 0;
3371}
3372
8a5cd31e 3373static void bus_detach_io_events(sd_bus *bus) {
1e05d493
LP
3374 assert(bus);
3375
3376 if (bus->input_io_event_source) {
3377 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
3378 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
3379 }
3380
3381 if (bus->output_io_event_source) {
3382 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
3383 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
3384 }
3385}
3386
8a5cd31e
LP
3387int bus_attach_inotify_event(sd_bus *bus) {
3388 int r;
3389
3390 assert(bus);
3391
3392 if (bus->inotify_fd < 0)
3393 return 0;
3394
3395 if (!bus->event)
3396 return 0;
3397
3398 if (!bus->inotify_event_source) {
3399 r = sd_event_add_io(bus->event, &bus->inotify_event_source, bus->inotify_fd, EPOLLIN, io_callback, bus);
3400 if (r < 0)
3401 return r;
3402
3403 r = sd_event_source_set_priority(bus->inotify_event_source, bus->event_priority);
3404 if (r < 0)
3405 return r;
3406
3407 r = sd_event_source_set_description(bus->inotify_event_source, "bus-inotify");
3408 } else
3409 r = sd_event_source_set_io_fd(bus->inotify_event_source, bus->inotify_fd);
3410 if (r < 0)
3411 return r;
3412
3413 return 0;
3414}
3415
3416static void bus_detach_inotify_event(sd_bus *bus) {
3417 assert(bus);
3418
3419 if (bus->inotify_event_source) {
3420 sd_event_source_set_enabled(bus->inotify_event_source, SD_EVENT_OFF);
3421 bus->inotify_event_source = sd_event_source_unref(bus->inotify_event_source);
3422 }
3423}
3424
d9f644e2 3425_public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
40ca29a1
LP
3426 int r;
3427
3428 assert_return(bus, -EINVAL);
40ca29a1
LP
3429 assert_return(!bus->event, -EBUSY);
3430
3431 assert(!bus->input_io_event_source);
3432 assert(!bus->output_io_event_source);
3433 assert(!bus->time_event_source);
3434
76b54375
LP
3435 if (event)
3436 bus->event = sd_event_ref(event);
3437 else {
3438 r = sd_event_default(&bus->event);
3439 if (r < 0)
3440 return r;
3441 }
40ca29a1 3442
1e05d493 3443 bus->event_priority = priority;
40ca29a1 3444
6a0f1f6d 3445 r = sd_event_add_time(bus->event, &bus->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, bus);
40ca29a1
LP
3446 if (r < 0)
3447 goto fail;
3448
3449 r = sd_event_source_set_priority(bus->time_event_source, priority);
3450 if (r < 0)
3451 goto fail;
3452
356779df 3453 r = sd_event_source_set_description(bus->time_event_source, "bus-time");
9021bb9f
TG
3454 if (r < 0)
3455 goto fail;
3456
151b9b96 3457 r = sd_event_add_exit(bus->event, &bus->quit_event_source, quit_callback, bus);
abc5fe72
LP
3458 if (r < 0)
3459 goto fail;
3460
356779df 3461 r = sd_event_source_set_description(bus->quit_event_source, "bus-exit");
9021bb9f
TG
3462 if (r < 0)
3463 goto fail;
3464
8a5cd31e
LP
3465 r = bus_attach_io_events(bus);
3466 if (r < 0)
3467 goto fail;
3468
3469 r = bus_attach_inotify_event(bus);
1e05d493
LP
3470 if (r < 0)
3471 goto fail;
3472
40ca29a1
LP
3473 return 0;
3474
3475fail:
3476 sd_bus_detach_event(bus);
3477 return r;
3478}
3479
d9f644e2 3480_public_ int sd_bus_detach_event(sd_bus *bus) {
40ca29a1 3481 assert_return(bus, -EINVAL);
a82cafb9
LP
3482
3483 if (!bus->event)
3484 return 0;
40ca29a1 3485
8a5cd31e
LP
3486 bus_detach_io_events(bus);
3487 bus_detach_inotify_event(bus);
40ca29a1 3488
86befb40
LP
3489 if (bus->time_event_source) {
3490 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
40ca29a1 3491 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
86befb40 3492 }
40ca29a1 3493
86befb40
LP
3494 if (bus->quit_event_source) {
3495 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
abc5fe72 3496 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
86befb40 3497 }
abc5fe72 3498
93f1bcf4 3499 bus->event = sd_event_unref(bus->event);
a82cafb9 3500 return 1;
40ca29a1 3501}
affff0b6 3502
2be44176
LP
3503_public_ sd_event* sd_bus_get_event(sd_bus *bus) {
3504 assert_return(bus, NULL);
3505
3506 return bus->event;
3507}
3508
19befb2d
LP
3509_public_ sd_bus_message* sd_bus_get_current_message(sd_bus *bus) {
3510 assert_return(bus, NULL);
3511
3512 return bus->current_message;
3513}
3514
3515_public_ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus) {
affff0b6
LP
3516 assert_return(bus, NULL);
3517
19befb2d 3518 return bus->current_slot;
affff0b6 3519}
76b54375 3520
caa82984
LP
3521_public_ sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus) {
3522 assert_return(bus, NULL);
3523
3524 return bus->current_handler;
3525}
3526
3527_public_ void* sd_bus_get_current_userdata(sd_bus *bus) {
3528 assert_return(bus, NULL);
3529
3530 return bus->current_userdata;
3531}
3532
76b54375
LP
3533static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
3534 sd_bus *b = NULL;
3535 int r;
3536
3537 assert(bus_open);
3538 assert(default_bus);
3539
3540 if (!ret)
3541 return !!*default_bus;
3542
3543 if (*default_bus) {
3544 *ret = sd_bus_ref(*default_bus);
3545 return 0;
3546 }
3547
3548 r = bus_open(&b);
3549 if (r < 0)
3550 return r;
3551
3552 b->default_bus_ptr = default_bus;
3553 b->tid = gettid();
3554 *default_bus = b;
3555
3556 *ret = b;
3557 return 1;
3558}
3559
3560_public_ int sd_bus_default_system(sd_bus **ret) {
76b54375
LP
3561 return bus_default(sd_bus_open_system, &default_system_bus, ret);
3562}
3563
76b54375 3564
fa2f8973 3565_public_ int sd_bus_default_user(sd_bus **ret) {
76b54375
LP
3566 return bus_default(sd_bus_open_user, &default_user_bus, ret);
3567}
3568
af08d2f9
LP
3569_public_ int sd_bus_default(sd_bus **ret) {
3570
3571 const char *e;
3572
3573 /* Let's try our best to reuse another cached connection. If
3574 * the starter bus type is set, connect via our normal
3575 * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that
3576 * we can share the connection with the user/system default
3577 * bus. */
3578
3579 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
3580 if (e) {
3581 if (streq(e, "system"))
3582 return sd_bus_default_system(ret);
09365592 3583 else if (STR_IN_SET(e, "user", "session"))
af08d2f9
LP
3584 return sd_bus_default_user(ret);
3585 }
3586
3587 /* No type is specified, so we have not other option than to
3588 * use the starter address if it is set. */
af08d2f9 3589 e = secure_getenv("DBUS_STARTER_ADDRESS");
b33652fe 3590 if (e)
af08d2f9 3591 return bus_default(sd_bus_open, &default_starter_bus, ret);
af08d2f9
LP
3592
3593 /* Finally, if nothing is set use the cached connection for
3594 * the right scope */
3595
3596 if (cg_pid_get_owner_uid(0, NULL) >= 0)
3597 return sd_bus_default_user(ret);
3598 else
3599 return sd_bus_default_system(ret);
3600}
3601
76b54375
LP
3602_public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
3603 assert_return(b, -EINVAL);
3604 assert_return(tid, -EINVAL);
3605 assert_return(!bus_pid_changed(b), -ECHILD);
3606
3607 if (b->tid != 0) {
3608 *tid = b->tid;
3609 return 0;
3610 }
3611
3612 if (b->event)
3613 return sd_event_get_tid(b->event, tid);
3614
3615 return -ENXIO;
3616}
28383ba1 3617
a6278b88
LP
3618_public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) {
3619 _cleanup_free_ char *e = NULL;
3620 char *ret;
3621
3622 assert_return(object_path_is_valid(prefix), -EINVAL);
3623 assert_return(external_id, -EINVAL);
3624 assert_return(ret_path, -EINVAL);
3625
3626 e = bus_label_escape(external_id);
3627 if (!e)
3628 return -ENOMEM;
3629
605405c6 3630 ret = strjoin(prefix, "/", e);
a6278b88
LP
3631 if (!ret)
3632 return -ENOMEM;
3633
3634 *ret_path = ret;
3635 return 0;
28383ba1
LP
3636}
3637
a6278b88
LP
3638_public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) {
3639 const char *e;
3640 char *ret;
3641
3642 assert_return(object_path_is_valid(path), -EINVAL);
3643 assert_return(object_path_is_valid(prefix), -EINVAL);
3644 assert_return(external_id, -EINVAL);
3645
3646 e = object_path_startswith(path, prefix);
3647 if (!e) {
3648 *external_id = NULL;
3649 return 0;
3650 }
3651
3652 ret = bus_label_unescape(e);
3653 if (!ret)
3654 return -ENOMEM;
3655
3656 *external_id = ret;
3657 return 1;
28383ba1 3658}
5b12334d 3659
dfb815c3
DH
3660_public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) {
3661 _cleanup_strv_free_ char **labels = NULL;
3662 char *path, *path_pos, **label_pos;
3663 const char *sep, *template_pos;
3664 size_t path_length;
3665 va_list list;
3666 int r;
3667
3668 assert_return(out, -EINVAL);
3669 assert_return(path_template, -EINVAL);
3670
3671 path_length = strlen(path_template);
3672
19932084 3673 va_start(list, path_template);
dfb815c3
DH
3674 for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) {
3675 const char *arg;
3676 char *label;
3677
3678 arg = va_arg(list, const char *);
3679 if (!arg) {
3680 va_end(list);
3681 return -EINVAL;
3682 }
3683
3684 label = bus_label_escape(arg);
3685 if (!label) {
3686 va_end(list);
3687 return -ENOMEM;
3688 }
3689
3690 r = strv_consume(&labels, label);
3691 if (r < 0) {
3692 va_end(list);
3693 return r;
3694 }
3695
3696 /* add label length, but account for the format character */
3697 path_length += strlen(label) - 1;
3698 }
3699 va_end(list);
3700
3701 path = malloc(path_length + 1);
3702 if (!path)
3703 return -ENOMEM;
3704
3705 path_pos = path;
3706 label_pos = labels;
3707
3708 for (template_pos = path_template; *template_pos; ) {
3709 sep = strchrnul(template_pos, '%');
3710 path_pos = mempcpy(path_pos, template_pos, sep - template_pos);
3711 if (!*sep)
3712 break;
3713
3714 path_pos = stpcpy(path_pos, *label_pos++);
3715 template_pos = sep + 1;
3716 }
3717
3718 *path_pos = 0;
3719 *out = path;
3720 return 0;
3721}
3722
3723_public_ int sd_bus_path_decode_many(const char *path, const char *path_template, ...) {
3724 _cleanup_strv_free_ char **labels = NULL;
3725 const char *template_pos, *path_pos;
3726 char **label_pos;
3727 va_list list;
3728 int r;
3729
3730 /*
3731 * This decodes an object-path based on a template argument. The
3732 * template consists of a verbatim path, optionally including special
3733 * directives:
3734 *
3735 * - Each occurrence of '%' in the template matches an arbitrary
3736 * substring of a label in the given path. At most one such
3737 * directive is allowed per label. For each such directive, the
3738 * caller must provide an output parameter (char **) via va_arg. If
3739 * NULL is passed, the given label is verified, but not returned.
3740 * For each matched label, the *decoded* label is stored in the
3741 * passed output argument, and the caller is responsible to free
3742 * it. Note that the output arguments are only modified if the
3743 * actualy path matched the template. Otherwise, they're left
3744 * untouched.
3745 *
3746 * This function returns <0 on error, 0 if the path does not match the
3747 * template, 1 if it matched.
3748 */
3749
3750 assert_return(path, -EINVAL);
3751 assert_return(path_template, -EINVAL);
3752
3753 path_pos = path;
3754
3755 for (template_pos = path_template; *template_pos; ) {
3756 const char *sep;
3757 size_t length;
3758 char *label;
3759
3760 /* verify everything until the next '%' matches verbatim */
3761 sep = strchrnul(template_pos, '%');
3762 length = sep - template_pos;
3763 if (strncmp(path_pos, template_pos, length))
3764 return 0;
3765
3766 path_pos += length;
3767 template_pos += length;
3768
3769 if (!*template_pos)
3770 break;
3771
3772 /* We found the next '%' character. Everything up until here
3773 * matched. We now skip ahead to the end of this label and make
3774 * sure it matches the tail of the label in the path. Then we
3775 * decode the string in-between and save it for later use. */
3776
3777 ++template_pos; /* skip over '%' */
3778
3779 sep = strchrnul(template_pos, '/');
3780 length = sep - template_pos; /* length of suffix to match verbatim */
3781
3782 /* verify the suffixes match */
3783 sep = strchrnul(path_pos, '/');
3784 if (sep - path_pos < (ssize_t)length ||
3785 strncmp(sep - length, template_pos, length))
3786 return 0;
3787
3788 template_pos += length; /* skip over matched label */
3789 length = sep - path_pos - length; /* length of sub-label to decode */
3790
3791 /* store unescaped label for later use */
3792 label = bus_label_unescape_n(path_pos, length);
3793 if (!label)
3794 return -ENOMEM;
3795
3796 r = strv_consume(&labels, label);
3797 if (r < 0)
3798 return r;
3799
3800 path_pos = sep; /* skip decoded label and suffix */
3801 }
3802
3803 /* end of template must match end of path */
3804 if (*path_pos)
3805 return 0;
3806
3807 /* copy the labels over to the caller */
19932084 3808 va_start(list, path_template);
dfb815c3
DH
3809 for (label_pos = labels; label_pos && *label_pos; ++label_pos) {
3810 char **arg;
3811
3812 arg = va_arg(list, char **);
3813 if (arg)
3814 *arg = *label_pos;
3815 else
3816 free(*label_pos);
3817 }
3818 va_end(list);
3819
86ed6d1b 3820 labels = mfree(labels);
dfb815c3
DH
3821 return 1;
3822}
3823
ae095f86 3824_public_ int sd_bus_try_close(sd_bus *bus) {
ae095f86 3825 assert_return(bus, -EINVAL);
ae095f86 3826 assert_return(!bus_pid_changed(bus), -ECHILD);
a3d59cd1 3827
a132bef0 3828 return -EOPNOTSUPP;
ae095f86 3829}
5972fe95 3830
455971c1 3831_public_ int sd_bus_get_description(sd_bus *bus, const char **description) {
5972fe95 3832 assert_return(bus, -EINVAL);
455971c1 3833 assert_return(description, -EINVAL);
f4b2933e 3834 assert_return(bus->description, -ENXIO);
5972fe95
LP
3835 assert_return(!bus_pid_changed(bus), -ECHILD);
3836
455971c1 3837 *description = bus->description;
5972fe95
LP
3838 return 0;
3839}
fe3f22d1
DK
3840
3841int bus_get_root_path(sd_bus *bus) {
3842 int r;
3843
3844 if (bus->cgroup_root)
3845 return 0;
3846
3847 r = cg_get_root_path(&bus->cgroup_root);
3848 if (r == -ENOENT) {
3849 bus->cgroup_root = strdup("/");
3850 if (!bus->cgroup_root)
3851 return -ENOMEM;
3852
3853 r = 0;
3854 }
3855
3856 return r;
3857}
3acc1daf
LP
3858
3859_public_ int sd_bus_get_scope(sd_bus *bus, const char **scope) {
3acc1daf
LP
3860 assert_return(bus, -EINVAL);
3861 assert_return(scope, -EINVAL);
3862 assert_return(!bus_pid_changed(bus), -ECHILD);
3863
3acc1daf
LP
3864 if (bus->is_user) {
3865 *scope = "user";
5b820358 3866 return 0;
3acc1daf
LP
3867 }
3868
3869 if (bus->is_system) {
3870 *scope = "system";
5b820358
LP
3871 return 0;
3872 }
3873
3874 return -ENODATA;
3875}
3876
3877_public_ int sd_bus_get_address(sd_bus *bus, const char **address) {
3878
3879 assert_return(bus, -EINVAL);
3880 assert_return(address, -EINVAL);
3881 assert_return(!bus_pid_changed(bus), -ECHILD);
3882
3883 if (bus->address) {
3884 *address = bus->address;
3885 return 0;
3acc1daf
LP
3886 }
3887
3888 return -ENODATA;
3889}
224b3787 3890
882897af 3891_public_ int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *mask) {
224b3787
LP
3892 assert_return(bus, -EINVAL);
3893 assert_return(mask, -EINVAL);
3894 assert_return(!bus_pid_changed(bus), -ECHILD);
3895
3896 *mask = bus->creds_mask;
3897 return 0;
3898}
3899
882897af 3900_public_ int sd_bus_is_bus_client(sd_bus *bus) {
224b3787
LP
3901 assert_return(bus, -EINVAL);
3902 assert_return(!bus_pid_changed(bus), -ECHILD);
3903
3904 return bus->bus_client;
3905}
3906
882897af 3907_public_ int sd_bus_is_server(sd_bus *bus) {
224b3787
LP
3908 assert_return(bus, -EINVAL);
3909 assert_return(!bus_pid_changed(bus), -ECHILD);
3910
3911 return bus->is_server;
3912}
3913
882897af 3914_public_ int sd_bus_is_anonymous(sd_bus *bus) {
224b3787
LP
3915 assert_return(bus, -EINVAL);
3916 assert_return(!bus_pid_changed(bus), -ECHILD);
3917
3918 return bus->anonymous_auth;
3919}
3920
882897af 3921_public_ int sd_bus_is_trusted(sd_bus *bus) {
224b3787
LP
3922 assert_return(bus, -EINVAL);
3923 assert_return(!bus_pid_changed(bus), -ECHILD);
3924
3925 return bus->trusted;
3926}
3927
882897af 3928_public_ int sd_bus_is_monitor(sd_bus *bus) {
224b3787
LP
3929 assert_return(bus, -EINVAL);
3930 assert_return(!bus_pid_changed(bus), -ECHILD);
3931
c7db1984 3932 return bus->is_monitor;
224b3787 3933}
fa2f8973
LP
3934
3935static void flush_close(sd_bus *bus) {
3936 if (!bus)
3937 return;
3938
3939 /* Flushes and closes the specified bus. We take a ref before,
3940 * to ensure the flushing does not cause the bus to be
3941 * unreferenced. */
3942
3943 sd_bus_flush_close_unref(sd_bus_ref(bus));
3944}
3945
3946_public_ void sd_bus_default_flush_close(void) {
3947 flush_close(default_starter_bus);
3948 flush_close(default_user_bus);
3949 flush_close(default_system_bus);
3950}
fbb4603d
LP
3951
3952_public_ int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b) {
3953 assert_return(bus, -EINVAL);
3954
3955 /* Turns on exit-on-disconnect, and triggers it immediately if the bus connection was already
3956 * disconnected. Note that this is triggered exclusively on disconnections triggered by the server side, never
3957 * from the client side. */
3958 bus->exit_on_disconnect = b;
3959
3960 /* If the exit condition was triggered already, exit immediately. */
3961 return bus_exit_now(bus);
3962}
3963
3964_public_ int sd_bus_get_exit_on_disconnect(sd_bus *bus) {
3965 assert_return(bus, -EINVAL);
3966
3967 return bus->exit_on_disconnect;
3968}
48ef41a3
LP
3969
3970_public_ int sd_bus_set_sender(sd_bus *bus, const char *sender) {
3971 assert_return(bus, -EINVAL);
3972 assert_return(!bus->bus_client, -EPERM);
3973 assert_return(!sender || service_name_is_valid(sender), -EINVAL);
3974
3975 return free_and_strdup(&bus->patch_sender, sender);
3976}
3977
3978_public_ int sd_bus_get_sender(sd_bus *bus, const char **ret) {
3979 assert_return(bus, -EINVAL);
3980 assert_return(ret, -EINVAL);
3981
3982 if (!bus->patch_sender)
3983 return -ENODATA;
3984
3985 *ret = bus->patch_sender;
3986 return 0;
3987}