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