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