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