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