]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/sd-bus.c
condition: don't include files from src/core
[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;
cf226cfc
LP
1099 b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
1100 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
af08d2f9
LP
1101
1102 r = sd_bus_start(b);
1103 if (r < 0)
1104 goto fail;
1105
1106 *ret = b;
1107 return 0;
1108
1109fail:
1110 bus_free(b);
1111 return r;
1112}
1113
09365592 1114int bus_set_address_system(sd_bus *b) {
de1c301e 1115 const char *e;
09365592
LP
1116 assert(b);
1117
1118 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
1119 if (e)
1120 return sd_bus_set_address(b, e);
1121
e3afaf6b 1122 return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS);
09365592
LP
1123}
1124
1125_public_ int sd_bus_open_system(sd_bus **ret) {
de1c301e
LP
1126 sd_bus *b;
1127 int r;
1128
d6888822 1129 assert_return(ret, -EINVAL);
de1c301e 1130
021a1e78
LP
1131 r = sd_bus_new(&b);
1132 if (r < 0)
1133 return r;
1134
09365592 1135 r = bus_set_address_system(b);
e3dd987c
LP
1136 if (r < 0)
1137 goto fail;
de1c301e 1138
94bbf1ba 1139 b->bus_client = true;
5972fe95 1140 b->is_system = true;
021a1e78 1141
adacb957
LP
1142 /* Let's do per-method access control on the system bus. We
1143 * need the caller's UID and capability set for that. */
1144 b->trusted = false;
1145 b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
cf226cfc 1146 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
adacb957 1147
021a1e78
LP
1148 r = sd_bus_start(b);
1149 if (r < 0)
1150 goto fail;
de1c301e
LP
1151
1152 *ret = b;
1153 return 0;
021a1e78
LP
1154
1155fail:
1156 bus_free(b);
1157 return r;
de1c301e
LP
1158}
1159
09365592 1160int bus_set_address_user(sd_bus *b) {
de1c301e 1161 const char *e;
de1c301e 1162
09365592 1163 assert(b);
021a1e78 1164
6c03089c 1165 e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
09365592
LP
1166 if (e)
1167 return sd_bus_set_address(b, e);
1168
1169 e = secure_getenv("XDG_RUNTIME_DIR");
de1c301e 1170 if (e) {
09365592 1171 _cleanup_free_ char *ee = NULL;
e3dd987c 1172
09365592
LP
1173 ee = bus_address_escape(e);
1174 if (!ee)
1175 return -ENOMEM;
e3dd987c 1176
626851be 1177#ifdef ENABLE_KDBUS
e3afaf6b 1178 (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, getuid(), ee);
626851be 1179#else
e3afaf6b 1180 (void) asprintf(&b->address, UNIX_USER_BUS_ADDRESS_FMT, ee);
626851be 1181#endif
09365592 1182 } else {
626851be 1183#ifdef ENABLE_KDBUS
e3afaf6b 1184 (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid());
626851be 1185#else
09365592 1186 return -ECONNREFUSED;
626851be 1187#endif
de1c301e
LP
1188 }
1189
09365592
LP
1190 if (!b->address)
1191 return -ENOMEM;
1192
1193 return 0;
1194}
1195
1196_public_ int sd_bus_open_user(sd_bus **ret) {
1197 sd_bus *b;
1198 int r;
1199
1200 assert_return(ret, -EINVAL);
1201
1202 r = sd_bus_new(&b);
1203 if (r < 0)
1204 return r;
1205
1206 r = bus_set_address_user(b);
1207 if (r < 0)
1208 return r;
1209
94bbf1ba 1210 b->bus_client = true;
5972fe95 1211 b->is_user = true;
de1c301e 1212
adacb957
LP
1213 /* We don't do any per-method access control on the user
1214 * bus. */
1215 b->trusted = true;
1216
021a1e78 1217 r = sd_bus_start(b);
2571ead1
LP
1218 if (r < 0)
1219 goto fail;
de1c301e
LP
1220
1221 *ret = b;
1222 return 0;
2571ead1
LP
1223
1224fail:
021a1e78 1225 bus_free(b);
2571ead1 1226 return r;
de1c301e
LP
1227}
1228
09365592 1229int bus_set_address_system_remote(sd_bus *b, const char *host) {
0f8bd8de 1230 _cleanup_free_ char *e = NULL;
7f0d207d 1231 char *m = NULL, *c = NULL;
0f8bd8de 1232
09365592
LP
1233 assert(b);
1234 assert(host);
0f8bd8de 1235
7f0d207d
LP
1236 /* Let's see if we shall enter some container */
1237 m = strchr(host, ':');
1238 if (m) {
1239 m++;
1240
1241 /* Let's make sure this is not a port of some kind,
1242 * and is a valid machine name. */
1243 if (!in_charset(m, "0123456789") && machine_name_is_valid(m)) {
1244 char *t;
1245
1246 /* Cut out the host part */
1247 t = strndupa(host, m - host - 1);
1248 e = bus_address_escape(t);
1249 if (!e)
1250 return -ENOMEM;
1251
1252 c = strappenda(",argv4=--machine=", m);
1253 }
1254 }
1255
1256 if (!e) {
1257 e = bus_address_escape(host);
1258 if (!e)
1259 return -ENOMEM;
1260 }
0f8bd8de 1261
7f0d207d 1262 b->address = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", c, NULL);
09365592 1263 if (!b->address)
0f8bd8de 1264 return -ENOMEM;
a7893c6b 1265
09365592
LP
1266 return 0;
1267 }
1268
1269_public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
1270 sd_bus *bus;
1271 int r;
1272
1273 assert_return(host, -EINVAL);
1274 assert_return(ret, -EINVAL);
1275
a7893c6b 1276 r = sd_bus_new(&bus);
09365592 1277 if (r < 0)
a7893c6b 1278 return r;
a7893c6b 1279
09365592
LP
1280 r = bus_set_address_system_remote(bus, host);
1281 if (r < 0)
1282 goto fail;
1283
a7893c6b 1284 bus->bus_client = true;
09365592 1285 bus->trusted = false;
3acc1daf 1286 bus->is_system = true;
a7893c6b
LP
1287
1288 r = sd_bus_start(bus);
09365592
LP
1289 if (r < 0)
1290 goto fail;
a7893c6b
LP
1291
1292 *ret = bus;
1293 return 0;
09365592
LP
1294
1295fail:
1296 bus_free(bus);
1297 return r;
a7893c6b
LP
1298}
1299
09365592 1300int bus_set_address_system_container(sd_bus *b, const char *machine) {
a7893c6b 1301 _cleanup_free_ char *e = NULL;
a7893c6b 1302
09365592
LP
1303 assert(b);
1304 assert(machine);
a7893c6b
LP
1305
1306 e = bus_address_escape(machine);
1307 if (!e)
1308 return -ENOMEM;
1309
9e554864 1310#ifdef ENABLE_KDBUS
09365592 1311 b->address = strjoin("x-container-kernel:machine=", e, ";x-container-unix:machine=", e, NULL);
9e554864 1312#else
09365592 1313 b->address = strjoin("x-container-unix:machine=", e, NULL);
9e554864 1314#endif
09365592 1315 if (!b->address)
a7893c6b 1316 return -ENOMEM;
0f8bd8de 1317
09365592
LP
1318 return 0;
1319}
1320
1321_public_ int sd_bus_open_system_container(sd_bus **ret, const char *machine) {
1322 sd_bus *bus;
1323 int r;
1324
1325 assert_return(machine, -EINVAL);
1326 assert_return(ret, -EINVAL);
affcf189 1327 assert_return(machine_name_is_valid(machine), -EINVAL);
09365592 1328
0f8bd8de 1329 r = sd_bus_new(&bus);
09365592 1330 if (r < 0)
0f8bd8de 1331 return r;
0f8bd8de 1332
09365592
LP
1333 r = bus_set_address_system_container(bus, machine);
1334 if (r < 0)
1335 goto fail;
1336
0f8bd8de 1337 bus->bus_client = true;
09365592 1338 bus->trusted = false;
3acc1daf 1339 bus->is_system = true;
0f8bd8de
LP
1340
1341 r = sd_bus_start(bus);
09365592
LP
1342 if (r < 0)
1343 goto fail;
0f8bd8de
LP
1344
1345 *ret = bus;
1346 return 0;
09365592
LP
1347
1348fail:
1349 bus_free(bus);
1350 return r;
0f8bd8de
LP
1351}
1352
d9f644e2 1353_public_ void sd_bus_close(sd_bus *bus) {
0e586eae 1354
de1c301e
LP
1355 if (!bus)
1356 return;
d5a2b9a6
LP
1357 if (bus->state == BUS_CLOSED)
1358 return;
1359 if (bus_pid_changed(bus))
f54514f3
LP
1360 return;
1361
1362 bus->state = BUS_CLOSED;
e82c9509 1363
40ca29a1
LP
1364 sd_bus_detach_event(bus);
1365
0e586eae
LP
1366 /* Drop all queued messages so that they drop references to
1367 * the bus object and the bus may be freed */
1368 bus_reset_queues(bus);
1369
f54514f3
LP
1370 if (!bus->is_kernel)
1371 bus_close_fds(bus);
1372
1373 /* We'll leave the fd open in case this is a kernel bus, since
1374 * there might still be memblocks around that reference this
cd6d5e1c 1375 * bus, and they might need to invoke the KDBUS_CMD_FREE
1d0e3c98 1376 * ioctl on the fd when they are freed. */
de1c301e
LP
1377}
1378
718db961
LP
1379static void bus_enter_closing(sd_bus *bus) {
1380 assert(bus);
1381
1382 if (bus->state != BUS_OPENING &&
1383 bus->state != BUS_AUTHENTICATING &&
1384 bus->state != BUS_HELLO &&
1385 bus->state != BUS_RUNNING)
1386 return;
1387
1388 bus->state = BUS_CLOSING;
1389}
1390
d9f644e2 1391_public_ sd_bus *sd_bus_ref(sd_bus *bus) {
9d6c7c82 1392 assert_return(bus, NULL);
de1c301e 1393
e4ee6e5c 1394 assert_se(REFCNT_INC(bus->n_ref) >= 2);
de1c301e 1395
de1c301e
LP
1396 return bus;
1397}
1398
d9f644e2 1399_public_ sd_bus *sd_bus_unref(sd_bus *bus) {
b7fc42e0 1400 unsigned i;
5b1bc83f
LP
1401
1402 if (!bus)
1403 return NULL;
de1c301e 1404
f389bf15
LP
1405 i = REFCNT_DEC(bus->n_ref);
1406 if (i > 0)
1407 return NULL;
1408
1409 bus_free(bus);
de1c301e
LP
1410 return NULL;
1411}
1412
d9f644e2 1413_public_ int sd_bus_is_open(sd_bus *bus) {
d6888822
LP
1414
1415 assert_return(bus, -EINVAL);
1416 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 1417
f54514f3 1418 return BUS_IS_OPEN(bus->state);
e3017af9
LP
1419}
1420
d9f644e2 1421_public_ int sd_bus_can_send(sd_bus *bus, char type) {
d728d708
LP
1422 int r;
1423
d6888822
LP
1424 assert_return(bus, -EINVAL);
1425 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
1426 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1427
09365592
LP
1428 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
1429 return 0;
1430
d728d708 1431 if (type == SD_BUS_TYPE_UNIX_FD) {
264ad849 1432 if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
021a1e78
LP
1433 return 0;
1434
20902f3e 1435 r = bus_ensure_running(bus);
d728d708
LP
1436 if (r < 0)
1437 return r;
de1c301e 1438
d728d708
LP
1439 return bus->can_fds;
1440 }
1441
1442 return bus_type_is_valid(type);
de1c301e
LP
1443}
1444
5c302692 1445_public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) {
d728d708 1446 int r;
de1c301e 1447
d6888822 1448 assert_return(bus, -EINVAL);
f7fce345 1449 assert_return(id, -EINVAL);
d6888822 1450 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1451
20902f3e 1452 r = bus_ensure_running(bus);
d728d708
LP
1453 if (r < 0)
1454 return r;
de1c301e 1455
f7fce345 1456 *id = bus->server_id;
d728d708 1457 return 0;
de1c301e
LP
1458}
1459
3df7a7e6 1460static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
7adc46fc 1461 assert(b);
de1c301e
LP
1462 assert(m);
1463
aea93deb
LP
1464 if (m->sealed) {
1465 /* If we copy the same message to multiple
693eb9a2 1466 * destinations, avoid using the same cookie
aea93deb 1467 * numbers. */
693eb9a2 1468 b->cookie = MAX(b->cookie, BUS_MESSAGE_COOKIE(m));
de1c301e 1469 return 0;
aea93deb 1470 }
de1c301e 1471
3df7a7e6
LP
1472 if (timeout == 0)
1473 timeout = BUS_DEFAULT_TIMEOUT;
1474
693eb9a2 1475 return bus_message_seal(m, ++b->cookie, timeout);
de1c301e
LP
1476}
1477
e1c433c6
LP
1478static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
1479 assert(b);
1480
6f285378 1481 /* Do packet version and endianness already match? */
e1c433c6
LP
1482 if ((b->message_version == 0 || b->message_version == (*m)->header->version) &&
1483 (b->message_endian == 0 || b->message_endian == (*m)->header->endian))
1484 return 0;
1485
1486 /* No? Then remarshal! */
1487 return bus_message_remarshal(b, m);
1488}
1489
7adc46fc
LP
1490int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
1491 assert(b);
1492 assert(m);
1493
7adc46fc
LP
1494 /* The bus specification says the serial number cannot be 0,
1495 * hence let's fill something in for synthetic messages. Since
1496 * synthetic messages might have a fake sender and we don't
1497 * want to interfere with the real sender's serial numbers we
6f285378 1498 * pick a fixed, artificial one. We use (uint32_t) -1 rather
7adc46fc
LP
1499 * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
1500 * even though kdbus can do 64bit. */
1501
3df7a7e6 1502 return bus_message_seal(m, 0xFFFFFFFFULL, 0);
7adc46fc
LP
1503}
1504
069f5e61 1505static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call, size_t *idx) {
2e3db52d
LP
1506 int r;
1507
718db961 1508 assert(bus);
2e3db52d 1509 assert(m);
718db961
LP
1510
1511 if (bus->is_kernel)
069f5e61 1512 r = bus_kernel_write_message(bus, m, hint_sync_call);
718db961 1513 else
2e3db52d
LP
1514 r = bus_socket_write_message(bus, m, idx);
1515
1516 if (r <= 0)
1517 return r;
1518
90911bb6 1519 if (bus->is_kernel || *idx >= BUS_MESSAGE_SIZE(m))
42c4ebcb 1520 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
1521 bus_message_type_to_string(m->header->type),
1522 strna(sd_bus_message_get_sender(m)),
1523 strna(sd_bus_message_get_destination(m)),
1524 strna(sd_bus_message_get_path(m)),
1525 strna(sd_bus_message_get_interface(m)),
1526 strna(sd_bus_message_get_member(m)),
42c4ebcb
LP
1527 BUS_MESSAGE_COOKIE(m),
1528 m->reply_cookie,
2e3db52d
LP
1529 strna(m->error.message));
1530
1531 return r;
718db961
LP
1532}
1533
de1c301e 1534static int dispatch_wqueue(sd_bus *bus) {
e3017af9 1535 int r, ret = 0;
de1c301e
LP
1536
1537 assert(bus);
89ffcd2a 1538 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1539
de1c301e
LP
1540 while (bus->wqueue_size > 0) {
1541
069f5e61 1542 r = bus_write_message(bus, bus->wqueue[0], false, &bus->windex);
718db961 1543 if (r < 0)
de1c301e 1544 return r;
718db961 1545 else if (r == 0)
e3017af9
LP
1546 /* Didn't do anything this time */
1547 return ret;
6629161f 1548 else if (bus->is_kernel || bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
de1c301e
LP
1549 /* Fully written. Let's drop the entry from
1550 * the queue.
1551 *
1552 * This isn't particularly optimized, but
1553 * well, this is supposed to be our worst-case
1554 * buffer only, and the socket buffer is
1555 * supposed to be our primary buffer, and if
1556 * it got full, then all bets are off
1557 * anyway. */
1558
de1c301e 1559 bus->wqueue_size --;
c4e6e242 1560 sd_bus_message_unref(bus->wqueue[0]);
de1c301e
LP
1561 memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
1562 bus->windex = 0;
1563
e3017af9 1564 ret = 1;
de1c301e
LP
1565 }
1566 }
1567
e3017af9 1568 return ret;
de1c301e
LP
1569}
1570
766c5809 1571static int bus_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
7d22c717
LP
1572 assert(bus);
1573
1574 if (bus->is_kernel)
766c5809 1575 return bus_kernel_read_message(bus, hint_priority, priority);
7d22c717
LP
1576 else
1577 return bus_socket_read_message(bus);
1578}
1579
7adc46fc 1580int bus_rqueue_make_room(sd_bus *bus) {
821e0756 1581 assert(bus);
7d22c717 1582
821e0756 1583 if (bus->rqueue_size >= BUS_RQUEUE_MAX)
7d22c717
LP
1584 return -ENOBUFS;
1585
821e0756 1586 if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_allocated, bus->rqueue_size + 1))
7d22c717
LP
1587 return -ENOMEM;
1588
7d22c717
LP
1589 return 0;
1590}
1591
766c5809 1592static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) {
e3017af9 1593 int r, ret = 0;
de1c301e
LP
1594
1595 assert(bus);
1596 assert(m);
89ffcd2a 1597 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1598
766c5809
LP
1599 /* Note that the priority logic is only available on kdbus,
1600 * where the rqueue is unused. We check the rqueue here
1601 * anyway, because it's simple... */
1602
7d22c717
LP
1603 for (;;) {
1604 if (bus->rqueue_size > 0) {
1605 /* Dispatch a queued message */
de1c301e 1606
7d22c717
LP
1607 *m = bus->rqueue[0];
1608 bus->rqueue_size --;
1609 memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
1610 return 1;
1611 }
de1c301e 1612
7d22c717 1613 /* Try to read a new message */
766c5809 1614 r = bus_read_message(bus, hint_priority, priority);
718db961 1615 if (r < 0)
e3017af9 1616 return r;
e3017af9
LP
1617 if (r == 0)
1618 return ret;
de1c301e 1619
2e8d788c 1620 ret = 1;
7d22c717 1621 }
de1c301e
LP
1622}
1623
069f5e61 1624static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie, bool hint_sync_call) {
e1c433c6 1625 _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e
LP
1626 int r;
1627
d6888822 1628 assert_return(bus, -EINVAL);
d6888822
LP
1629 assert_return(m, -EINVAL);
1630 assert_return(!bus_pid_changed(bus), -ECHILD);
09365592 1631 assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
021a1e78 1632
a3d59cd1
LP
1633 if (!BUS_IS_OPEN(bus->state))
1634 return -ENOTCONN;
1635
021a1e78
LP
1636 if (m->n_fds > 0) {
1637 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1638 if (r < 0)
1639 return r;
1640 if (r == 0)
1641 return -ENOTSUP;
1642 }
de1c301e 1643
693eb9a2 1644 /* If the cookie number isn't kept, then we know that no reply
29f6aadd 1645 * is expected */
693eb9a2 1646 if (!cookie && !m->sealed)
0461f8cd 1647 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
29f6aadd 1648
3df7a7e6 1649 r = bus_seal_message(bus, m, 0);
de1c301e
LP
1650 if (r < 0)
1651 return r;
1652
441d56a1 1653 /* Remarshall if we have to. This will possibly unref the
e1c433c6
LP
1654 * message and place a replacement in m */
1655 r = bus_remarshal_message(bus, &m);
1656 if (r < 0)
1657 return r;
1658
5407f2de
LP
1659 /* If this is a reply and no reply was requested, then let's
1660 * suppress this, if we can */
693eb9a2 1661 if (m->dont_send && !cookie)
7a37d625 1662 return 1;
5407f2de 1663
89ffcd2a 1664 if ((bus->state == BUS_RUNNING || bus->state == BUS_HELLO) && bus->wqueue_size <= 0) {
de1c301e
LP
1665 size_t idx = 0;
1666
069f5e61 1667 r = bus_write_message(bus, m, hint_sync_call, &idx);
32f46480 1668 if (r < 0) {
441d56a1 1669 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 1670 bus_enter_closing(bus);
441d56a1
LP
1671 return -ECONNRESET;
1672 }
32f46480 1673
de1c301e 1674 return r;
32f46480 1675 } else if (!bus->is_kernel && idx < BUS_MESSAGE_SIZE(m)) {
de1c301e
LP
1676 /* Wasn't fully written. So let's remember how
1677 * much was written. Note that the first entry
1678 * of the wqueue array is always allocated so
1679 * that we always can remember how much was
1680 * written. */
1681 bus->wqueue[0] = sd_bus_message_ref(m);
1682 bus->wqueue_size = 1;
1683 bus->windex = idx;
1684 }
1685 } else {
de1c301e
LP
1686 /* Just append it to the queue. */
1687
25220239 1688 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
de1c301e
LP
1689 return -ENOBUFS;
1690
821e0756 1691 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
de1c301e
LP
1692 return -ENOMEM;
1693
821e0756 1694 bus->wqueue[bus->wqueue_size ++] = sd_bus_message_ref(m);
de1c301e
LP
1695 }
1696
693eb9a2
LP
1697 if (cookie)
1698 *cookie = BUS_MESSAGE_COOKIE(m);
de1c301e 1699
7a37d625 1700 return 1;
de1c301e
LP
1701}
1702
069f5e61
LP
1703_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie) {
1704 return bus_send_internal(bus, m, cookie, false);
1705}
1706
693eb9a2 1707_public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) {
911121a7
LP
1708 int r;
1709
1710 assert_return(bus, -EINVAL);
911121a7
LP
1711 assert_return(m, -EINVAL);
1712 assert_return(!bus_pid_changed(bus), -ECHILD);
1713
a3d59cd1
LP
1714 if (!BUS_IS_OPEN(bus->state))
1715 return -ENOTCONN;
1716
911121a7
LP
1717 if (!streq_ptr(m->destination, destination)) {
1718
1719 if (!destination)
1720 return -EEXIST;
1721
1722 r = sd_bus_message_set_destination(m, destination);
1723 if (r < 0)
1724 return r;
1725 }
1726
693eb9a2 1727 return sd_bus_send(bus, m, cookie);
911121a7
LP
1728}
1729
de1c301e
LP
1730static usec_t calc_elapse(uint64_t usec) {
1731 if (usec == (uint64_t) -1)
1732 return 0;
1733
de1c301e
LP
1734 return now(CLOCK_MONOTONIC) + usec;
1735}
1736
e3017af9
LP
1737static int timeout_compare(const void *a, const void *b) {
1738 const struct reply_callback *x = a, *y = b;
1739
1740 if (x->timeout != 0 && y->timeout == 0)
1741 return -1;
1742
1743 if (x->timeout == 0 && y->timeout != 0)
1744 return 1;
1745
1746 if (x->timeout < y->timeout)
1747 return -1;
1748
1749 if (x->timeout > y->timeout)
1750 return 1;
1751
1752 return 0;
1753}
1754
c49b30a2 1755_public_ int sd_bus_call_async(
de1c301e 1756 sd_bus *bus,
19befb2d 1757 sd_bus_slot **slot,
e1c433c6 1758 sd_bus_message *_m,
52f3ba91 1759 sd_bus_message_handler_t callback,
de1c301e 1760 void *userdata,
19befb2d 1761 uint64_t usec) {
de1c301e 1762
e1c433c6 1763 _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
19befb2d 1764 _cleanup_bus_slot_unref_ sd_bus_slot *s = NULL;
de1c301e
LP
1765 int r;
1766
d6888822 1767 assert_return(bus, -EINVAL);
d6888822 1768 assert_return(m, -EINVAL);
40ca29a1 1769 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
0461f8cd 1770 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
d6888822
LP
1771 assert_return(callback, -EINVAL);
1772 assert_return(!bus_pid_changed(bus), -ECHILD);
09365592 1773 assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
89ffcd2a 1774
a3d59cd1
LP
1775 if (!BUS_IS_OPEN(bus->state))
1776 return -ENOTCONN;
1777
c9fe4af7 1778 r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
89ffcd2a
LP
1779 if (r < 0)
1780 return r;
de1c301e 1781
3df7a7e6
LP
1782 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1783 if (r < 0)
1784 return r;
e3017af9 1785
3df7a7e6 1786 r = bus_seal_message(bus, m, usec);
de1c301e
LP
1787 if (r < 0)
1788 return r;
1789
e1c433c6
LP
1790 r = bus_remarshal_message(bus, &m);
1791 if (r < 0)
1792 return r;
1793
19befb2d
LP
1794 s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
1795 if (!s)
de1c301e
LP
1796 return -ENOMEM;
1797
19befb2d 1798 s->reply_callback.callback = callback;
de1c301e 1799
19befb2d 1800 s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
c9fe4af7 1801 r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
de1c301e 1802 if (r < 0) {
19befb2d 1803 s->reply_callback.cookie = 0;
de1c301e
LP
1804 return r;
1805 }
1806
19befb2d
LP
1807 s->reply_callback.timeout = calc_elapse(m->timeout);
1808 if (s->reply_callback.timeout != 0) {
1809 r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
e3017af9 1810 if (r < 0) {
19befb2d 1811 s->reply_callback.timeout = 0;
e3017af9
LP
1812 return r;
1813 }
1814 }
1815
19befb2d
LP
1816 r = sd_bus_send(bus, m, &s->reply_callback.cookie);
1817 if (r < 0)
de1c301e 1818 return r;
de1c301e 1819
19befb2d
LP
1820 if (slot)
1821 *slot = s;
1822 s = NULL;
e3017af9 1823
19befb2d 1824 return r;
de1c301e
LP
1825}
1826
20902f3e 1827int bus_ensure_running(sd_bus *bus) {
89ffcd2a
LP
1828 int r;
1829
1830 assert(bus);
1831
718db961 1832 if (bus->state == BUS_UNSET || bus->state == BUS_CLOSED || bus->state == BUS_CLOSING)
021a1e78 1833 return -ENOTCONN;
d728d708
LP
1834 if (bus->state == BUS_RUNNING)
1835 return 1;
89ffcd2a
LP
1836
1837 for (;;) {
1838 r = sd_bus_process(bus, NULL);
1839 if (r < 0)
1840 return r;
d728d708
LP
1841 if (bus->state == BUS_RUNNING)
1842 return 1;
e3017af9
LP
1843 if (r > 0)
1844 continue;
89ffcd2a
LP
1845
1846 r = sd_bus_wait(bus, (uint64_t) -1);
1847 if (r < 0)
1848 return r;
1849 }
1850}
1851
97f82db3 1852_public_ int sd_bus_call(
de1c301e 1853 sd_bus *bus,
97f82db3 1854 sd_bus_message *_m,
de1c301e
LP
1855 uint64_t usec,
1856 sd_bus_error *error,
1857 sd_bus_message **reply) {
1858
97f82db3 1859 _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e 1860 usec_t timeout;
693eb9a2 1861 uint64_t cookie;
7d22c717
LP
1862 unsigned i;
1863 int r;
de1c301e 1864
97f82db3 1865 assert_return(bus, -EINVAL);
97f82db3
KS
1866 assert_return(m, -EINVAL);
1867 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
1868 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
1869 assert_return(!bus_error_is_dirty(error), -EINVAL);
1870 assert_return(!bus_pid_changed(bus), -ECHILD);
09365592 1871 assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
97f82db3 1872
a3d59cd1
LP
1873 if (!BUS_IS_OPEN(bus->state))
1874 return -ENOTCONN;
1875
97f82db3
KS
1876 r = bus_ensure_running(bus);
1877 if (r < 0)
1878 return r;
1879
a43b9ca3 1880 i = bus->rqueue_size;
97f82db3
KS
1881
1882 r = bus_seal_message(bus, m, usec);
1883 if (r < 0)
1884 return r;
1885
1886 r = bus_remarshal_message(bus, &m);
1887 if (r < 0)
1888 return r;
1889
069f5e61 1890 r = bus_send_internal(bus, m, &cookie, true);
de1c301e
LP
1891 if (r < 0)
1892 return r;
1893
3df7a7e6 1894 timeout = calc_elapse(m->timeout);
de1c301e
LP
1895
1896 for (;;) {
1897 usec_t left;
de1c301e 1898
7d22c717
LP
1899 while (i < bus->rqueue_size) {
1900 sd_bus_message *incoming = NULL;
1901
1902 incoming = bus->rqueue[i];
89ffcd2a 1903
693eb9a2 1904 if (incoming->reply_cookie == cookie) {
de1c301e
LP
1905 /* Found a match! */
1906
7d22c717
LP
1907 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1908 bus->rqueue_size--;
1909
40ca29a1 1910 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
b7f247e0 1911
2ce97e2b
LP
1912 if (incoming->n_fds <= 0 || (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
1913 if (reply)
1914 *reply = incoming;
1915 else
1916 sd_bus_message_unref(incoming);
1917
1918 return 1;
1919 }
1920
1921 r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
b7f247e0 1922
a43b9ca3 1923 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
de1c301e 1924 r = sd_bus_error_copy(error, &incoming->error);
a43b9ca3
LP
1925 else
1926 r = -EIO;
de1c301e
LP
1927
1928 sd_bus_message_unref(incoming);
a43b9ca3 1929 return r;
a8a07f89 1930
693eb9a2 1931 } else if (BUS_MESSAGE_COOKIE(incoming) == cookie &&
a8a07f89
LP
1932 bus->unique_name &&
1933 incoming->sender &&
1934 streq(bus->unique_name, incoming->sender)) {
1935
7d22c717
LP
1936 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1937 bus->rqueue_size--;
1938
a8a07f89
LP
1939 /* Our own message? Somebody is trying
1940 * to send its own client a message,
1941 * let's not dead-lock, let's fail
1942 * immediately. */
1943
1944 sd_bus_message_unref(incoming);
1945 return -ELOOP;
de1c301e
LP
1946 }
1947
de1c301e 1948 /* Try to read more, right-away */
7d22c717 1949 i++;
de1c301e 1950 }
7d22c717 1951
766c5809 1952 r = bus_read_message(bus, false, 0);
32f46480 1953 if (r < 0) {
441d56a1 1954 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 1955 bus_enter_closing(bus);
441d56a1
LP
1956 return -ECONNRESET;
1957 }
32f46480 1958
a43b9ca3 1959 return r;
32f46480 1960 }
7d22c717 1961 if (r > 0)
e3017af9 1962 continue;
de1c301e
LP
1963
1964 if (timeout > 0) {
1965 usec_t n;
1966
1967 n = now(CLOCK_MONOTONIC);
1968 if (n >= timeout)
1969 return -ETIMEDOUT;
1970
1971 left = timeout - n;
1972 } else
1973 left = (uint64_t) -1;
1974
e3017af9 1975 r = bus_poll(bus, true, left);
de1c301e
LP
1976 if (r < 0)
1977 return r;
f8e11cda
LP
1978 if (r == 0)
1979 return -ETIMEDOUT;
de1c301e
LP
1980
1981 r = dispatch_wqueue(bus);
32f46480 1982 if (r < 0) {
441d56a1 1983 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 1984 bus_enter_closing(bus);
441d56a1
LP
1985 return -ECONNRESET;
1986 }
32f46480 1987
de1c301e 1988 return r;
32f46480 1989 }
de1c301e
LP
1990 }
1991}
1992
d9f644e2 1993_public_ int sd_bus_get_fd(sd_bus *bus) {
d6888822
LP
1994
1995 assert_return(bus, -EINVAL);
d6888822
LP
1996 assert_return(bus->input_fd == bus->output_fd, -EPERM);
1997 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1998
e82c9509 1999 return bus->input_fd;
de1c301e
LP
2000}
2001
d9f644e2 2002_public_ int sd_bus_get_events(sd_bus *bus) {
de1c301e
LP
2003 int flags = 0;
2004
d6888822 2005 assert_return(bus, -EINVAL);
d6888822 2006 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2007
a3d59cd1
LP
2008 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
2009 return -ENOTCONN;
2010
de1c301e
LP
2011 if (bus->state == BUS_OPENING)
2012 flags |= POLLOUT;
89ffcd2a
LP
2013 else if (bus->state == BUS_AUTHENTICATING) {
2014
2181a7f5 2015 if (bus_socket_auth_needs_write(bus))
89ffcd2a
LP
2016 flags |= POLLOUT;
2017
2018 flags |= POLLIN;
2019
2020 } else if (bus->state == BUS_RUNNING || bus->state == BUS_HELLO) {
de1c301e
LP
2021 if (bus->rqueue_size <= 0)
2022 flags |= POLLIN;
2023 if (bus->wqueue_size > 0)
2024 flags |= POLLOUT;
2025 }
2026
2027 return flags;
2028}
2029
d9f644e2 2030_public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
e3017af9
LP
2031 struct reply_callback *c;
2032
d6888822
LP
2033 assert_return(bus, -EINVAL);
2034 assert_return(timeout_usec, -EINVAL);
d6888822 2035 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 2036
a3d59cd1
LP
2037 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
2038 return -ENOTCONN;
2039
8f8f05a9
LP
2040 if (bus->track_queue) {
2041 *timeout_usec = 0;
2042 return 1;
2043 }
2044
718db961
LP
2045 if (bus->state == BUS_CLOSING) {
2046 *timeout_usec = 0;
2047 return 1;
2048 }
2049
e3017af9
LP
2050 if (bus->state == BUS_AUTHENTICATING) {
2051 *timeout_usec = bus->auth_timeout;
2052 return 1;
2053 }
2054
adee69fa
LP
2055 if (bus->state != BUS_RUNNING && bus->state != BUS_HELLO) {
2056 *timeout_usec = (uint64_t) -1;
e3017af9 2057 return 0;
adee69fa 2058 }
e3017af9 2059
8efd6381
LP
2060 if (bus->rqueue_size > 0) {
2061 *timeout_usec = 0;
2062 return 1;
2063 }
2064
e3017af9 2065 c = prioq_peek(bus->reply_callbacks_prioq);
adee69fa
LP
2066 if (!c) {
2067 *timeout_usec = (uint64_t) -1;
e3017af9 2068 return 0;
adee69fa 2069 }
e3017af9 2070
19befb2d
LP
2071 if (c->timeout == 0) {
2072 *timeout_usec = (uint64_t) -1;
2073 return 0;
2074 }
2075
e3017af9
LP
2076 *timeout_usec = c->timeout;
2077 return 1;
2078}
2079
2080static int process_timeout(sd_bus *bus) {
ebcf1f97 2081 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
eb01ba5d 2082 _cleanup_bus_message_unref_ sd_bus_message* m = NULL;
e3017af9 2083 struct reply_callback *c;
1b64f838 2084 sd_bus_slot *slot;
e3017af9
LP
2085 usec_t n;
2086 int r;
2087
2088 assert(bus);
2089
2090 c = prioq_peek(bus->reply_callbacks_prioq);
2091 if (!c)
2092 return 0;
2093
2094 n = now(CLOCK_MONOTONIC);
2095 if (c->timeout > n)
2096 return 0;
2097
eb01ba5d
LP
2098 r = bus_message_new_synthetic_error(
2099 bus,
693eb9a2 2100 c->cookie,
14c24659 2101 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
eb01ba5d
LP
2102 &m);
2103 if (r < 0)
2104 return r;
2105
34a2c9e8
LP
2106 m->sender = "org.freedesktop.DBus";
2107
7adc46fc 2108 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2109 if (r < 0)
2110 return r;
2111
e3017af9 2112 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
19befb2d
LP
2113 c->timeout = 0;
2114
c9fe4af7 2115 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
19befb2d
LP
2116 c->cookie = 0;
2117
1b64f838 2118 slot = container_of(c, sd_bus_slot, reply_callback);
e3017af9 2119
718db961
LP
2120 bus->iteration_counter ++;
2121
1b64f838
LP
2122 bus->current_message = m;
2123 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2124 bus->current_handler = c->callback;
2125 bus->current_userdata = slot->userdata;
1b64f838 2126 r = c->callback(bus, m, slot->userdata, &error_buffer);
caa82984
LP
2127 bus->current_userdata = NULL;
2128 bus->current_handler = NULL;
d974ad05 2129 bus->current_slot = NULL;
19befb2d 2130 bus->current_message = NULL;
718db961 2131
1b64f838
LP
2132 if (slot->floating) {
2133 bus_slot_disconnect(slot);
2134 sd_bus_slot_unref(slot);
2135 }
2136
d974ad05
DH
2137 sd_bus_slot_unref(slot);
2138
1b64f838 2139 return bus_maybe_reply_error(m, r, &error_buffer);
e3017af9
LP
2140}
2141
9d373862
LP
2142static int process_hello(sd_bus *bus, sd_bus_message *m) {
2143 assert(bus);
2144 assert(m);
2145
2146 if (bus->state != BUS_HELLO)
2147 return 0;
2148
2149 /* Let's make sure the first message on the bus is the HELLO
2150 * reply. But note that we don't actually parse the message
2181a7f5
LP
2151 * here (we leave that to the usual handling), we just verify
2152 * we don't let any earlier msg through. */
9d373862 2153
40ca29a1
LP
2154 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
2155 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
9d373862
LP
2156 return -EIO;
2157
19befb2d 2158 if (m->reply_cookie != 1)
9d373862
LP
2159 return -EIO;
2160
2161 return 0;
2162}
2163
a652755d 2164static int process_reply(sd_bus *bus, sd_bus_message *m) {
2ce97e2b 2165 _cleanup_bus_message_unref_ sd_bus_message *synthetic_reply = NULL;
ebcf1f97 2166 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
19befb2d 2167 struct reply_callback *c;
1b64f838 2168 sd_bus_slot *slot;
a652755d
LP
2169 int r;
2170
2171 assert(bus);
2172 assert(m);
2173
40ca29a1
LP
2174 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
2175 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
a652755d
LP
2176 return 0;
2177
09365592
LP
2178 if (bus->is_kernel && (bus->hello_flags & KDBUS_HELLO_MONITOR))
2179 return 0;
2180
2181 if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
2182 return 0;
2183
c9fe4af7 2184 c = ordered_hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
a652755d
LP
2185 if (!c)
2186 return 0;
2187
19befb2d 2188 c->cookie = 0;
19befb2d 2189
1b64f838 2190 slot = container_of(c, sd_bus_slot, reply_callback);
a652755d 2191
2ce97e2b
LP
2192 if (m->n_fds > 0 && !(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
2193
2194 /* If the reply contained a file descriptor which we
2195 * didn't want we pass an error instead. */
2196
2197 r = bus_message_new_synthetic_error(
2198 bus,
2199 m->reply_cookie,
2200 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptor"),
2201 &synthetic_reply);
2202 if (r < 0)
1b64f838 2203 return r;
2ce97e2b
LP
2204
2205 r = bus_seal_synthetic_message(bus, synthetic_reply);
2206 if (r < 0)
1b64f838 2207 return r;
2ce97e2b
LP
2208
2209 m = synthetic_reply;
2210 } else {
2211 r = sd_bus_message_rewind(m, true);
2212 if (r < 0)
1b64f838 2213 return r;
2ce97e2b 2214 }
88fe224c 2215
1b64f838
LP
2216 if (c->timeout != 0) {
2217 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2218 c->timeout = 0;
2219 }
19befb2d 2220
1b64f838 2221 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2222 bus->current_handler = c->callback;
2223 bus->current_userdata = slot->userdata;
1b64f838 2224 r = c->callback(bus, m, slot->userdata, &error_buffer);
caa82984
LP
2225 bus->current_userdata = NULL;
2226 bus->current_handler = NULL;
d974ad05 2227 bus->current_slot = NULL;
a652755d 2228
19befb2d
LP
2229 if (slot->floating) {
2230 bus_slot_disconnect(slot);
2231 sd_bus_slot_unref(slot);
2232 }
2233
d974ad05
DH
2234 sd_bus_slot_unref(slot);
2235
1b64f838 2236 return bus_maybe_reply_error(m, r, &error_buffer);
a652755d
LP
2237}
2238
2239static int process_filter(sd_bus *bus, sd_bus_message *m) {
ebcf1f97 2240 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
a652755d
LP
2241 struct filter_callback *l;
2242 int r;
2243
392d5b37
LP
2244 assert(bus);
2245 assert(m);
2246
7286037f
LP
2247 do {
2248 bus->filter_callbacks_modified = false;
2249
2250 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
1b64f838 2251 sd_bus_slot *slot;
7286037f
LP
2252
2253 if (bus->filter_callbacks_modified)
2254 break;
2255
2256 /* Don't run this more than once per iteration */
2257 if (l->last_iteration == bus->iteration_counter)
2258 continue;
2259
2260 l->last_iteration = bus->iteration_counter;
2261
88fe224c
LP
2262 r = sd_bus_message_rewind(m, true);
2263 if (r < 0)
2264 return r;
2265
1b64f838
LP
2266 slot = container_of(l, sd_bus_slot, filter_callback);
2267
2268 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2269 bus->current_handler = l->callback;
2270 bus->current_userdata = slot->userdata;
1b64f838 2271 r = l->callback(bus, m, slot->userdata, &error_buffer);
caa82984
LP
2272 bus->current_userdata = NULL;
2273 bus->current_handler = NULL;
1b64f838 2274 bus->current_slot = sd_bus_slot_unref(slot);
19befb2d 2275
ebcf1f97 2276 r = bus_maybe_reply_error(m, r, &error_buffer);
7286037f
LP
2277 if (r != 0)
2278 return r;
2279
2280 }
2281
2282 } while (bus->filter_callbacks_modified);
a652755d
LP
2283
2284 return 0;
2285}
2286
392d5b37 2287static int process_match(sd_bus *bus, sd_bus_message *m) {
7286037f
LP
2288 int r;
2289
392d5b37
LP
2290 assert(bus);
2291 assert(m);
2292
7286037f
LP
2293 do {
2294 bus->match_callbacks_modified = false;
2295
eb01ba5d 2296 r = bus_match_run(bus, &bus->match_callbacks, m);
7286037f
LP
2297 if (r != 0)
2298 return r;
2299
2300 } while (bus->match_callbacks_modified);
2301
2302 return 0;
392d5b37
LP
2303}
2304
b9bf7e2b
LP
2305static int process_builtin(sd_bus *bus, sd_bus_message *m) {
2306 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2307 int r;
2308
2309 assert(bus);
2310 assert(m);
2311
09365592
LP
2312 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2313 return 0;
2314
758bf0c7
LP
2315 if (bus->manual_peer_interface)
2316 return 0;
2317
40ca29a1 2318 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
b9bf7e2b
LP
2319 return 0;
2320
2321 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
2322 return 0;
2323
0461f8cd 2324 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
b9bf7e2b
LP
2325 return 1;
2326
2327 if (streq_ptr(m->member, "Ping"))
df2d202e 2328 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2329 else if (streq_ptr(m->member, "GetMachineId")) {
2330 sd_id128_t id;
2331 char sid[33];
2332
2333 r = sd_id128_get_machine(&id);
2334 if (r < 0)
2335 return r;
2336
df2d202e 2337 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2338 if (r < 0)
2339 return r;
2340
2341 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
2342 } else {
29ddb38f 2343 r = sd_bus_message_new_method_errorf(
df2d202e 2344 m, &reply,
40ca29a1 2345 SD_BUS_ERROR_UNKNOWN_METHOD,
b9bf7e2b 2346 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
b9bf7e2b
LP
2347 }
2348
2349 if (r < 0)
2350 return r;
2351
2352 r = sd_bus_send(bus, reply, NULL);
2353 if (r < 0)
2354 return r;
2355
2356 return 1;
2357}
2358
2ce97e2b
LP
2359static int process_fd_check(sd_bus *bus, sd_bus_message *m) {
2360 assert(bus);
2361 assert(m);
2362
2363 /* If we got a message with a file descriptor which we didn't
2364 * want to accept, then let's drop it. How can this even
2365 * happen? For example, when the kernel queues a message into
2366 * an activatable names's queue which allows fds, and then is
2367 * delivered to us later even though we ourselves did not
2368 * negotiate it. */
2369
09365592
LP
2370 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2371 return 0;
2372
2ce97e2b
LP
2373 if (m->n_fds <= 0)
2374 return 0;
2375
2376 if (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2377 return 0;
2378
2379 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
2380 return 1; /* just eat it up */
2381
2382 return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Message contains file descriptors, which I cannot accept. Sorry.");
2383}
2384
992c052c 2385static int process_message(sd_bus *bus, sd_bus_message *m) {
e3017af9
LP
2386 int r;
2387
2388 assert(bus);
992c052c 2389 assert(m);
e3017af9 2390
19befb2d 2391 bus->current_message = m;
992c052c 2392 bus->iteration_counter++;
e3017af9 2393
42c4ebcb 2394 log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s",
4cdf0751 2395 bus_message_type_to_string(m->header->type),
40ca29a1 2396 strna(sd_bus_message_get_sender(m)),
4cdf0751 2397 strna(sd_bus_message_get_destination(m)),
40ca29a1
LP
2398 strna(sd_bus_message_get_path(m)),
2399 strna(sd_bus_message_get_interface(m)),
4cdf0751 2400 strna(sd_bus_message_get_member(m)),
42c4ebcb
LP
2401 BUS_MESSAGE_COOKIE(m),
2402 m->reply_cookie,
4cdf0751 2403 strna(m->error.message));
40ca29a1 2404
992c052c
LP
2405 r = process_hello(bus, m);
2406 if (r != 0)
affff0b6 2407 goto finish;
a652755d 2408
992c052c
LP
2409 r = process_reply(bus, m);
2410 if (r != 0)
affff0b6 2411 goto finish;
e3017af9 2412
2ce97e2b
LP
2413 r = process_fd_check(bus, m);
2414 if (r != 0)
2415 goto finish;
2416
992c052c
LP
2417 r = process_filter(bus, m);
2418 if (r != 0)
affff0b6 2419 goto finish;
a652755d 2420
992c052c
LP
2421 r = process_match(bus, m);
2422 if (r != 0)
affff0b6 2423 goto finish;
a652755d 2424
992c052c
LP
2425 r = process_builtin(bus, m);
2426 if (r != 0)
affff0b6
LP
2427 goto finish;
2428
2429 r = bus_process_object(bus, m);
a652755d 2430
affff0b6 2431finish:
19befb2d 2432 bus->current_message = NULL;
affff0b6 2433 return r;
29ddb38f 2434}
88fe224c 2435
8f8f05a9
LP
2436static int dispatch_track(sd_bus *bus) {
2437 assert(bus);
2438
2439 if (!bus->track_queue)
2440 return 0;
2441
2442 bus_track_dispatch(bus->track_queue);
2443 return 1;
2444}
2445
766c5809 2446static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
992c052c 2447 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
29ddb38f 2448 int r;
a652755d 2449
29ddb38f 2450 assert(bus);
992c052c 2451 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
7286037f 2452
992c052c
LP
2453 r = process_timeout(bus);
2454 if (r != 0)
2455 goto null_message;
7286037f 2456
992c052c
LP
2457 r = dispatch_wqueue(bus);
2458 if (r != 0)
2459 goto null_message;
7286037f 2460
8f8f05a9
LP
2461 r = dispatch_track(bus);
2462 if (r != 0)
2463 goto null_message;
2464
766c5809 2465 r = dispatch_rqueue(bus, hint_priority, priority, &m);
992c052c
LP
2466 if (r < 0)
2467 return r;
2468 if (!m)
2469 goto null_message;
7286037f 2470
992c052c
LP
2471 r = process_message(bus, m);
2472 if (r != 0)
2473 goto null_message;
7286037f 2474
992c052c
LP
2475 if (ret) {
2476 r = sd_bus_message_rewind(m, true);
29ddb38f
LP
2477 if (r < 0)
2478 return r;
e3017af9 2479
992c052c
LP
2480 *ret = m;
2481 m = NULL;
2482 return 1;
2483 }
a652755d 2484
40ca29a1 2485 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
a652755d 2486
dc74ce9b
LP
2487 log_debug("Unprocessed message call sender=%s object=%s interface=%s member=%s",
2488 strna(sd_bus_message_get_sender(m)),
2489 strna(sd_bus_message_get_path(m)),
2490 strna(sd_bus_message_get_interface(m)),
2491 strna(sd_bus_message_get_member(m)));
2492
992c052c 2493 r = sd_bus_reply_method_errorf(
df2d202e 2494 m,
40ca29a1 2495 SD_BUS_ERROR_UNKNOWN_OBJECT,
992c052c 2496 "Unknown object '%s'.", m->path);
29ddb38f
LP
2497 if (r < 0)
2498 return r;
2499 }
e3017af9 2500
992c052c 2501 return 1;
0a72c2bd 2502
992c052c
LP
2503null_message:
2504 if (r >= 0 && ret)
2505 *ret = NULL;
0a72c2bd 2506
992c052c 2507 return r;
29ddb38f 2508}
0a72c2bd 2509
fb6d9b77
LP
2510static void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m) {
2511 assert(bus);
2512 assert(m);
2513
2514 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus.Local";
2515 m->creds.well_known_names_local = true;
2516 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
2517}
2518
718db961
LP
2519static int process_closing(sd_bus *bus, sd_bus_message **ret) {
2520 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2521 struct reply_callback *c;
2522 int r;
2523
2524 assert(bus);
2525 assert(bus->state == BUS_CLOSING);
2526
c9fe4af7 2527 c = ordered_hashmap_first(bus->reply_callbacks);
718db961 2528 if (c) {
ebcf1f97 2529 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
1b64f838 2530 sd_bus_slot *slot;
ebcf1f97 2531
718db961
LP
2532 /* First, fail all outstanding method calls */
2533 r = bus_message_new_synthetic_error(
2534 bus,
693eb9a2 2535 c->cookie,
14c24659 2536 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
718db961
LP
2537 &m);
2538 if (r < 0)
2539 return r;
2540
7adc46fc 2541 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2542 if (r < 0)
2543 return r;
2544
19befb2d 2545 if (c->timeout != 0) {
718db961 2546 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
19befb2d
LP
2547 c->timeout = 0;
2548 }
718db961 2549
c9fe4af7 2550 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
19befb2d
LP
2551 c->cookie = 0;
2552
1b64f838 2553 slot = container_of(c, sd_bus_slot, reply_callback);
718db961 2554
718db961
LP
2555 bus->iteration_counter++;
2556
1b64f838
LP
2557 bus->current_message = m;
2558 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2559 bus->current_handler = c->callback;
2560 bus->current_userdata = slot->userdata;
1b64f838 2561 r = c->callback(bus, m, slot->userdata, &error_buffer);
caa82984
LP
2562 bus->current_userdata = NULL;
2563 bus->current_handler = NULL;
d974ad05 2564 bus->current_slot = NULL;
1b64f838
LP
2565 bus->current_message = NULL;
2566
2567 if (slot->floating) {
2568 bus_slot_disconnect(slot);
2569 sd_bus_slot_unref(slot);
2570 }
718db961 2571
d974ad05
DH
2572 sd_bus_slot_unref(slot);
2573
1b64f838 2574 return bus_maybe_reply_error(m, r, &error_buffer);
718db961
LP
2575 }
2576
2577 /* Then, synthesize a Disconnected message */
2578 r = sd_bus_message_new_signal(
2579 bus,
151b9b96 2580 &m,
718db961
LP
2581 "/org/freedesktop/DBus/Local",
2582 "org.freedesktop.DBus.Local",
151b9b96 2583 "Disconnected");
718db961
LP
2584 if (r < 0)
2585 return r;
2586
fb6d9b77 2587 bus_message_set_sender_local(bus, m);
34a2c9e8 2588
7adc46fc 2589 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2590 if (r < 0)
2591 return r;
2592
2593 sd_bus_close(bus);
2594
19befb2d 2595 bus->current_message = m;
718db961
LP
2596 bus->iteration_counter++;
2597
2598 r = process_filter(bus, m);
2599 if (r != 0)
2600 goto finish;
2601
2602 r = process_match(bus, m);
2603 if (r != 0)
2604 goto finish;
2605
2606 if (ret) {
2607 *ret = m;
2608 m = NULL;
2609 }
2610
2611 r = 1;
2612
2613finish:
19befb2d
LP
2614 bus->current_message = NULL;
2615
718db961
LP
2616 return r;
2617}
2618
766c5809 2619static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
8ce2afd6 2620 BUS_DONT_DESTROY(bus);
29ddb38f 2621 int r;
0a72c2bd 2622
992c052c
LP
2623 /* Returns 0 when we didn't do anything. This should cause the
2624 * caller to invoke sd_bus_wait() before returning the next
2625 * time. Returns > 0 when we did something, which possibly
2626 * means *ret is filled in with an unprocessed message. */
0a72c2bd 2627
d6888822
LP
2628 assert_return(bus, -EINVAL);
2629 assert_return(!bus_pid_changed(bus), -ECHILD);
0a72c2bd 2630
992c052c 2631 /* We don't allow recursively invoking sd_bus_process(). */
19befb2d
LP
2632 assert_return(!bus->current_message, -EBUSY);
2633 assert(!bus->current_slot);
0a72c2bd 2634
992c052c 2635 switch (bus->state) {
0a72c2bd 2636
992c052c 2637 case BUS_UNSET:
992c052c 2638 return -ENOTCONN;
0a72c2bd 2639
6d6f4904
LP
2640 case BUS_CLOSED:
2641 return -ECONNRESET;
2642
992c052c
LP
2643 case BUS_OPENING:
2644 r = bus_socket_process_opening(bus);
441d56a1 2645 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2646 bus_enter_closing(bus);
2647 r = 1;
2648 } else if (r < 0)
29ddb38f 2649 return r;
992c052c
LP
2650 if (ret)
2651 *ret = NULL;
a652755d
LP
2652 return r;
2653
992c052c 2654 case BUS_AUTHENTICATING:
992c052c 2655 r = bus_socket_process_authenticating(bus);
441d56a1 2656 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2657 bus_enter_closing(bus);
2658 r = 1;
2659 } else if (r < 0)
29ddb38f 2660 return r;
718db961 2661
992c052c
LP
2662 if (ret)
2663 *ret = NULL;
718db961 2664
992c052c 2665 return r;
a652755d 2666
992c052c
LP
2667 case BUS_RUNNING:
2668 case BUS_HELLO:
766c5809 2669 r = process_running(bus, hint_priority, priority, ret);
441d56a1 2670 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2671 bus_enter_closing(bus);
2672 r = 1;
2673
2674 if (ret)
2675 *ret = NULL;
2676 }
43a43f50 2677
43a43f50 2678 return r;
718db961
LP
2679
2680 case BUS_CLOSING:
2681 return process_closing(bus, ret);
992c052c 2682 }
43a43f50 2683
992c052c 2684 assert_not_reached("Unknown state");
e3017af9
LP
2685}
2686
766c5809
LP
2687_public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
2688 return bus_process_internal(bus, false, 0, ret);
2689}
2690
2691_public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) {
2692 return bus_process_internal(bus, true, priority, ret);
2693}
2694
992c052c
LP
2695static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2696 struct pollfd p[2] = {};
2697 int r, e, n;
2698 struct timespec ts;
3a43da28 2699 usec_t m = USEC_INFINITY;
adcdb374
LP
2700
2701 assert(bus);
718db961
LP
2702
2703 if (bus->state == BUS_CLOSING)
2704 return 1;
2705
a3d59cd1
LP
2706 if (!BUS_IS_OPEN(bus->state))
2707 return -ENOTCONN;
adcdb374 2708
992c052c
LP
2709 e = sd_bus_get_events(bus);
2710 if (e < 0)
2711 return e;
adcdb374 2712
992c052c 2713 if (need_more)
8efd6381
LP
2714 /* The caller really needs some more data, he doesn't
2715 * care about what's already read, or any timeouts
ad67ef27 2716 * except its own. */
992c052c 2717 e |= POLLIN;
992c052c 2718 else {
8efd6381
LP
2719 usec_t until;
2720 /* The caller wants to process if there's something to
2721 * process, but doesn't care otherwise */
2722
2723 r = sd_bus_get_timeout(bus, &until);
2724 if (r < 0)
2725 return r;
2726 if (r > 0) {
2727 usec_t nw;
2728 nw = now(CLOCK_MONOTONIC);
2729 m = until > nw ? until - nw : 0;
2730 }
992c052c 2731 }
adcdb374 2732
992c052c
LP
2733 if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
2734 m = timeout_usec;
adcdb374 2735
992c052c
LP
2736 p[0].fd = bus->input_fd;
2737 if (bus->output_fd == bus->input_fd) {
2738 p[0].events = e;
2739 n = 1;
2740 } else {
2741 p[0].events = e & POLLIN;
2742 p[1].fd = bus->output_fd;
2743 p[1].events = e & POLLOUT;
2744 n = 2;
adcdb374
LP
2745 }
2746
992c052c 2747 r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
adcdb374 2748 if (r < 0)
992c052c 2749 return -errno;
adcdb374 2750
992c052c 2751 return r > 0 ? 1 : 0;
adcdb374
LP
2752}
2753
d9f644e2 2754_public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
9db76355 2755
d6888822 2756 assert_return(bus, -EINVAL);
d6888822 2757 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2758
718db961
LP
2759 if (bus->state == BUS_CLOSING)
2760 return 0;
2761
a3d59cd1
LP
2762 if (!BUS_IS_OPEN(bus->state))
2763 return -ENOTCONN;
718db961 2764
992c052c
LP
2765 if (bus->rqueue_size > 0)
2766 return 0;
9db76355 2767
992c052c
LP
2768 return bus_poll(bus, false, timeout_usec);
2769}
9db76355 2770
d9f644e2 2771_public_ int sd_bus_flush(sd_bus *bus) {
992c052c 2772 int r;
9db76355 2773
d6888822 2774 assert_return(bus, -EINVAL);
d6888822 2775 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2776
718db961
LP
2777 if (bus->state == BUS_CLOSING)
2778 return 0;
2779
a3d59cd1
LP
2780 if (!BUS_IS_OPEN(bus->state))
2781 return -ENOTCONN;
718db961 2782
992c052c
LP
2783 r = bus_ensure_running(bus);
2784 if (r < 0)
2785 return r;
9db76355 2786
992c052c
LP
2787 if (bus->wqueue_size <= 0)
2788 return 0;
9db76355 2789
992c052c
LP
2790 for (;;) {
2791 r = dispatch_wqueue(bus);
32f46480 2792 if (r < 0) {
441d56a1 2793 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 2794 bus_enter_closing(bus);
441d56a1
LP
2795 return -ECONNRESET;
2796 }
32f46480 2797
9db76355 2798 return r;
32f46480 2799 }
9db76355 2800
992c052c
LP
2801 if (bus->wqueue_size <= 0)
2802 return 0;
9db76355 2803
992c052c 2804 r = bus_poll(bus, false, (uint64_t) -1);
9db76355
LP
2805 if (r < 0)
2806 return r;
9db76355 2807 }
9db76355
LP
2808}
2809
19befb2d
LP
2810_public_ int sd_bus_add_filter(
2811 sd_bus *bus,
2812 sd_bus_slot **slot,
2813 sd_bus_message_handler_t callback,
2814 void *userdata) {
d9f644e2 2815
19befb2d 2816 sd_bus_slot *s;
de1c301e 2817
d6888822
LP
2818 assert_return(bus, -EINVAL);
2819 assert_return(callback, -EINVAL);
2820 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2821
19befb2d
LP
2822 s = bus_slot_allocate(bus, !slot, BUS_FILTER_CALLBACK, sizeof(struct filter_callback), userdata);
2823 if (!s)
29ddb38f
LP
2824 return -ENOMEM;
2825
19befb2d 2826 s->filter_callback.callback = callback;
a652755d 2827
19befb2d
LP
2828 bus->filter_callbacks_modified = true;
2829 LIST_PREPEND(callbacks, bus->filter_callbacks, &s->filter_callback);
a652755d 2830
19befb2d
LP
2831 if (slot)
2832 *slot = s;
29ddb38f 2833
992c052c 2834 return 0;
a652755d 2835}
392d5b37 2836
19befb2d
LP
2837_public_ int sd_bus_add_match(
2838 sd_bus *bus,
2839 sd_bus_slot **slot,
2840 const char *match,
2841 sd_bus_message_handler_t callback,
2842 void *userdata) {
d9f644e2 2843
992c052c
LP
2844 struct bus_match_component *components = NULL;
2845 unsigned n_components = 0;
2915234d 2846 sd_bus_slot *s = NULL;
992c052c 2847 int r = 0;
392d5b37 2848
d6888822
LP
2849 assert_return(bus, -EINVAL);
2850 assert_return(match, -EINVAL);
2851 assert_return(!bus_pid_changed(bus), -ECHILD);
392d5b37 2852
992c052c
LP
2853 r = bus_match_parse(match, &components, &n_components);
2854 if (r < 0)
2855 goto finish;
29ddb38f 2856
19befb2d
LP
2857 s = bus_slot_allocate(bus, !slot, BUS_MATCH_CALLBACK, sizeof(struct match_callback), userdata);
2858 if (!s) {
2859 r = -ENOMEM;
2860 goto finish;
2861 }
2862
2863 s->match_callback.callback = callback;
2864 s->match_callback.cookie = ++bus->match_cookie;
2865
992c052c 2866 if (bus->bus_client) {
29ddb38f 2867
19befb2d
LP
2868 if (!bus->is_kernel) {
2869 /* When this is not a kernel transport, we
2870 * store the original match string, so that we
2871 * can use it to remove the match again */
2872
2873 s->match_callback.match_string = strdup(match);
2874 if (!s->match_callback.match_string) {
2875 r = -ENOMEM;
2876 goto finish;
2877 }
2878 }
2879
2880 r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components, s->match_callback.cookie);
992c052c
LP
2881 if (r < 0)
2882 goto finish;
392d5b37
LP
2883 }
2884
992c052c 2885 bus->match_callbacks_modified = true;
19befb2d
LP
2886 r = bus_match_add(&bus->match_callbacks, components, n_components, &s->match_callback);
2887 if (r < 0)
2888 goto finish;
2889
2890 if (slot)
2891 *slot = s;
2892 s = NULL;
917b5dc7 2893
992c052c
LP
2894finish:
2895 bus_match_parse_free(components, n_components);
19befb2d
LP
2896 sd_bus_slot_unref(s);
2897
992c052c 2898 return r;
917b5dc7
LP
2899}
2900
19befb2d
LP
2901int bus_remove_match_by_string(
2902 sd_bus *bus,
2903 const char *match,
2904 sd_bus_message_handler_t callback,
2905 void *userdata) {
d9f644e2 2906
992c052c
LP
2907 struct bus_match_component *components = NULL;
2908 unsigned n_components = 0;
19befb2d
LP
2909 struct match_callback *c;
2910 int r = 0;
917b5dc7 2911
d6888822
LP
2912 assert_return(bus, -EINVAL);
2913 assert_return(match, -EINVAL);
2914 assert_return(!bus_pid_changed(bus), -ECHILD);
917b5dc7 2915
992c052c 2916 r = bus_match_parse(match, &components, &n_components);
29ddb38f 2917 if (r < 0)
19befb2d 2918 goto finish;
f10dda3b 2919
19befb2d
LP
2920 r = bus_match_find(&bus->match_callbacks, components, n_components, NULL, NULL, &c);
2921 if (r <= 0)
2922 goto finish;
f10dda3b 2923
19befb2d 2924 sd_bus_slot_unref(container_of(c, sd_bus_slot, match_callback));
f10dda3b 2925
19befb2d 2926finish:
992c052c 2927 bus_match_parse_free(components, n_components);
f10dda3b 2928
19befb2d 2929 return r;
f10dda3b
LP
2930}
2931
992c052c
LP
2932bool bus_pid_changed(sd_bus *bus) {
2933 assert(bus);
f10dda3b 2934
992c052c
LP
2935 /* We don't support people creating a bus connection and
2936 * keeping it around over a fork(). Let's complain. */
d5a2b9a6 2937
992c052c 2938 return bus->original_pid != getpid();
d5a2b9a6 2939}
40ca29a1
LP
2940
2941static int io_callback(sd_event_source *s, int fd, uint32_t revents, 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 time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
0927756b 2955 sd_bus *bus = userdata;
40ca29a1
LP
2956 int r;
2957
2958 assert(bus);
2959
2960 r = sd_bus_process(bus, NULL);
2961 if (r < 0)
2962 return r;
2963
2964 return 1;
2965}
2966
2967static int prepare_callback(sd_event_source *s, void *userdata) {
2968 sd_bus *bus = userdata;
2969 int r, e;
2970 usec_t until;
2971
2972 assert(s);
2973 assert(bus);
2974
2975 e = sd_bus_get_events(bus);
2976 if (e < 0)
2977 return e;
2978
2979 if (bus->output_fd != bus->input_fd) {
2980
2981 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
2982 if (r < 0)
2983 return r;
2984
2985 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
2986 if (r < 0)
2987 return r;
2988 } else {
2989 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
2990 if (r < 0)
2991 return r;
2992 }
2993
2994 r = sd_bus_get_timeout(bus, &until);
2995 if (r < 0)
2996 return r;
2997 if (r > 0) {
2998 int j;
2999
3000 j = sd_event_source_set_time(bus->time_event_source, until);
3001 if (j < 0)
3002 return j;
3003 }
3004
3005 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
3006 if (r < 0)
3007 return r;
3008
3009 return 1;
3010}
3011
abc5fe72
LP
3012static int quit_callback(sd_event_source *event, void *userdata) {
3013 sd_bus *bus = userdata;
3014
3015 assert(event);
3016
3017 sd_bus_flush(bus);
7bb4d371 3018 sd_bus_close(bus);
abc5fe72
LP
3019
3020 return 1;
3021}
3022
1e05d493
LP
3023static int attach_io_events(sd_bus *bus) {
3024 int r;
3025
3026 assert(bus);
3027
3028 if (bus->input_fd < 0)
3029 return 0;
3030
3031 if (!bus->event)
3032 return 0;
3033
3034 if (!bus->input_io_event_source) {
151b9b96 3035 r = sd_event_add_io(bus->event, &bus->input_io_event_source, bus->input_fd, 0, io_callback, bus);
1e05d493
LP
3036 if (r < 0)
3037 return r;
3038
3039 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
3040 if (r < 0)
3041 return r;
3042
3043 r = sd_event_source_set_priority(bus->input_io_event_source, bus->event_priority);
9021bb9f
TG
3044 if (r < 0)
3045 return r;
3046
356779df 3047 r = sd_event_source_set_description(bus->input_io_event_source, "bus-input");
1e05d493
LP
3048 } else
3049 r = sd_event_source_set_io_fd(bus->input_io_event_source, bus->input_fd);
3050
3051 if (r < 0)
3052 return r;
3053
3054 if (bus->output_fd != bus->input_fd) {
3055 assert(bus->output_fd >= 0);
3056
3057 if (!bus->output_io_event_source) {
151b9b96 3058 r = sd_event_add_io(bus->event, &bus->output_io_event_source, bus->output_fd, 0, io_callback, bus);
1e05d493
LP
3059 if (r < 0)
3060 return r;
3061
3062 r = sd_event_source_set_priority(bus->output_io_event_source, bus->event_priority);
9021bb9f
TG
3063 if (r < 0)
3064 return r;
3065
356779df 3066 r = sd_event_source_set_description(bus->input_io_event_source, "bus-output");
1e05d493
LP
3067 } else
3068 r = sd_event_source_set_io_fd(bus->output_io_event_source, bus->output_fd);
3069
3070 if (r < 0)
3071 return r;
3072 }
3073
3074 return 0;
3075}
3076
3077static void detach_io_events(sd_bus *bus) {
3078 assert(bus);
3079
3080 if (bus->input_io_event_source) {
3081 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
3082 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
3083 }
3084
3085 if (bus->output_io_event_source) {
3086 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
3087 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
3088 }
3089}
3090
d9f644e2 3091_public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
40ca29a1
LP
3092 int r;
3093
3094 assert_return(bus, -EINVAL);
40ca29a1
LP
3095 assert_return(!bus->event, -EBUSY);
3096
3097 assert(!bus->input_io_event_source);
3098 assert(!bus->output_io_event_source);
3099 assert(!bus->time_event_source);
3100
76b54375
LP
3101 if (event)
3102 bus->event = sd_event_ref(event);
3103 else {
3104 r = sd_event_default(&bus->event);
3105 if (r < 0)
3106 return r;
3107 }
40ca29a1 3108
1e05d493 3109 bus->event_priority = priority;
40ca29a1 3110
6a0f1f6d 3111 r = sd_event_add_time(bus->event, &bus->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, bus);
40ca29a1
LP
3112 if (r < 0)
3113 goto fail;
3114
3115 r = sd_event_source_set_priority(bus->time_event_source, priority);
3116 if (r < 0)
3117 goto fail;
3118
356779df 3119 r = sd_event_source_set_description(bus->time_event_source, "bus-time");
9021bb9f
TG
3120 if (r < 0)
3121 goto fail;
3122
151b9b96 3123 r = sd_event_add_exit(bus->event, &bus->quit_event_source, quit_callback, bus);
abc5fe72
LP
3124 if (r < 0)
3125 goto fail;
3126
356779df 3127 r = sd_event_source_set_description(bus->quit_event_source, "bus-exit");
9021bb9f
TG
3128 if (r < 0)
3129 goto fail;
3130
1e05d493
LP
3131 r = attach_io_events(bus);
3132 if (r < 0)
3133 goto fail;
3134
40ca29a1
LP
3135 return 0;
3136
3137fail:
3138 sd_bus_detach_event(bus);
3139 return r;
3140}
3141
d9f644e2 3142_public_ int sd_bus_detach_event(sd_bus *bus) {
40ca29a1 3143 assert_return(bus, -EINVAL);
a82cafb9
LP
3144
3145 if (!bus->event)
3146 return 0;
40ca29a1 3147
1e05d493 3148 detach_io_events(bus);
40ca29a1 3149
86befb40
LP
3150 if (bus->time_event_source) {
3151 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
40ca29a1 3152 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
86befb40 3153 }
40ca29a1 3154
86befb40
LP
3155 if (bus->quit_event_source) {
3156 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
abc5fe72 3157 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
86befb40 3158 }
abc5fe72 3159
93f1bcf4 3160 bus->event = sd_event_unref(bus->event);
a82cafb9 3161 return 1;
40ca29a1 3162}
affff0b6 3163
2be44176
LP
3164_public_ sd_event* sd_bus_get_event(sd_bus *bus) {
3165 assert_return(bus, NULL);
3166
3167 return bus->event;
3168}
3169
19befb2d
LP
3170_public_ sd_bus_message* sd_bus_get_current_message(sd_bus *bus) {
3171 assert_return(bus, NULL);
3172
3173 return bus->current_message;
3174}
3175
3176_public_ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus) {
affff0b6
LP
3177 assert_return(bus, NULL);
3178
19befb2d 3179 return bus->current_slot;
affff0b6 3180}
76b54375 3181
caa82984
LP
3182_public_ sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus) {
3183 assert_return(bus, NULL);
3184
3185 return bus->current_handler;
3186}
3187
3188_public_ void* sd_bus_get_current_userdata(sd_bus *bus) {
3189 assert_return(bus, NULL);
3190
3191 return bus->current_userdata;
3192}
3193
76b54375
LP
3194static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
3195 sd_bus *b = NULL;
3196 int r;
3197
3198 assert(bus_open);
3199 assert(default_bus);
3200
3201 if (!ret)
3202 return !!*default_bus;
3203
3204 if (*default_bus) {
3205 *ret = sd_bus_ref(*default_bus);
3206 return 0;
3207 }
3208
3209 r = bus_open(&b);
3210 if (r < 0)
3211 return r;
3212
3213 b->default_bus_ptr = default_bus;
3214 b->tid = gettid();
3215 *default_bus = b;
3216
3217 *ret = b;
3218 return 1;
3219}
3220
3221_public_ int sd_bus_default_system(sd_bus **ret) {
ec202eae 3222 static thread_local sd_bus *default_system_bus = NULL;
76b54375
LP
3223
3224 return bus_default(sd_bus_open_system, &default_system_bus, ret);
3225}
3226
3227_public_ int sd_bus_default_user(sd_bus **ret) {
ec202eae 3228 static thread_local sd_bus *default_user_bus = NULL;
76b54375
LP
3229
3230 return bus_default(sd_bus_open_user, &default_user_bus, ret);
3231}
3232
af08d2f9
LP
3233_public_ int sd_bus_default(sd_bus **ret) {
3234
3235 const char *e;
3236
3237 /* Let's try our best to reuse another cached connection. If
3238 * the starter bus type is set, connect via our normal
3239 * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that
3240 * we can share the connection with the user/system default
3241 * bus. */
3242
3243 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
3244 if (e) {
3245 if (streq(e, "system"))
3246 return sd_bus_default_system(ret);
09365592 3247 else if (STR_IN_SET(e, "user", "session"))
af08d2f9
LP
3248 return sd_bus_default_user(ret);
3249 }
3250
3251 /* No type is specified, so we have not other option than to
3252 * use the starter address if it is set. */
3253
3254 e = secure_getenv("DBUS_STARTER_ADDRESS");
3255 if (e) {
3256 static thread_local sd_bus *default_starter_bus = NULL;
3257
3258 return bus_default(sd_bus_open, &default_starter_bus, ret);
3259 }
3260
3261 /* Finally, if nothing is set use the cached connection for
3262 * the right scope */
3263
3264 if (cg_pid_get_owner_uid(0, NULL) >= 0)
3265 return sd_bus_default_user(ret);
3266 else
3267 return sd_bus_default_system(ret);
3268}
3269
76b54375
LP
3270_public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
3271 assert_return(b, -EINVAL);
3272 assert_return(tid, -EINVAL);
3273 assert_return(!bus_pid_changed(b), -ECHILD);
3274
3275 if (b->tid != 0) {
3276 *tid = b->tid;
3277 return 0;
3278 }
3279
3280 if (b->event)
3281 return sd_event_get_tid(b->event, tid);
3282
3283 return -ENXIO;
3284}
28383ba1 3285
a6278b88
LP
3286_public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) {
3287 _cleanup_free_ char *e = NULL;
3288 char *ret;
3289
3290 assert_return(object_path_is_valid(prefix), -EINVAL);
3291 assert_return(external_id, -EINVAL);
3292 assert_return(ret_path, -EINVAL);
3293
3294 e = bus_label_escape(external_id);
3295 if (!e)
3296 return -ENOMEM;
3297
3298 ret = strjoin(prefix, "/", e, NULL);
3299 if (!ret)
3300 return -ENOMEM;
3301
3302 *ret_path = ret;
3303 return 0;
28383ba1
LP
3304}
3305
a6278b88
LP
3306_public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) {
3307 const char *e;
3308 char *ret;
3309
3310 assert_return(object_path_is_valid(path), -EINVAL);
3311 assert_return(object_path_is_valid(prefix), -EINVAL);
3312 assert_return(external_id, -EINVAL);
3313
3314 e = object_path_startswith(path, prefix);
3315 if (!e) {
3316 *external_id = NULL;
3317 return 0;
3318 }
3319
3320 ret = bus_label_unescape(e);
3321 if (!ret)
3322 return -ENOMEM;
3323
3324 *external_id = ret;
3325 return 1;
28383ba1 3326}
5b12334d 3327
ae095f86
LP
3328_public_ int sd_bus_try_close(sd_bus *bus) {
3329 int r;
3330
3331 assert_return(bus, -EINVAL);
ae095f86 3332 assert_return(!bus_pid_changed(bus), -ECHILD);
a3d59cd1
LP
3333
3334 if (!bus->is_kernel)
3335 return -ENOTSUP;
3336
3337 if (!BUS_IS_OPEN(bus->state))
3338 return -ENOTCONN;
ae095f86 3339
bd746b8b
LP
3340 if (bus->rqueue_size > 0)
3341 return -EBUSY;
3342
14f862a5
LP
3343 if (bus->wqueue_size > 0)
3344 return -EBUSY;
3345
ae095f86
LP
3346 r = bus_kernel_try_close(bus);
3347 if (r < 0)
3348 return r;
3349
3350 sd_bus_close(bus);
3351 return 0;
3352}
5972fe95 3353
455971c1 3354_public_ int sd_bus_get_description(sd_bus *bus, const char **description) {
5972fe95 3355 assert_return(bus, -EINVAL);
455971c1 3356 assert_return(description, -EINVAL);
f4b2933e 3357 assert_return(bus->description, -ENXIO);
5972fe95
LP
3358 assert_return(!bus_pid_changed(bus), -ECHILD);
3359
455971c1 3360 *description = bus->description;
5972fe95
LP
3361 return 0;
3362}
fe3f22d1
DK
3363
3364int bus_get_root_path(sd_bus *bus) {
3365 int r;
3366
3367 if (bus->cgroup_root)
3368 return 0;
3369
3370 r = cg_get_root_path(&bus->cgroup_root);
3371 if (r == -ENOENT) {
3372 bus->cgroup_root = strdup("/");
3373 if (!bus->cgroup_root)
3374 return -ENOMEM;
3375
3376 r = 0;
3377 }
3378
3379 return r;
3380}
3acc1daf
LP
3381
3382_public_ int sd_bus_get_scope(sd_bus *bus, const char **scope) {
3383 int r;
3384
3385 assert_return(bus, -EINVAL);
3386 assert_return(scope, -EINVAL);
3387 assert_return(!bus_pid_changed(bus), -ECHILD);
3388
3389 if (bus->is_kernel) {
3390 _cleanup_free_ char *n = NULL;
3391 const char *dash;
3392
3393 r = bus_kernel_get_bus_name(bus, &n);
3394 if (r < 0)
3395 return r;
3396
3397 if (streq(n, "0-system")) {
3398 *scope = "system";
5b820358 3399 return 0;
3acc1daf
LP
3400 }
3401
3402 dash = strchr(n, '-');
d2df88ff 3403 if (streq_ptr(dash, "-user")) {
3acc1daf 3404 *scope = "user";
5b820358 3405 return 0;
3acc1daf
LP
3406 }
3407 }
3408
3409 if (bus->is_user) {
3410 *scope = "user";
5b820358 3411 return 0;
3acc1daf
LP
3412 }
3413
3414 if (bus->is_system) {
3415 *scope = "system";
5b820358
LP
3416 return 0;
3417 }
3418
3419 return -ENODATA;
3420}
3421
3422_public_ int sd_bus_get_address(sd_bus *bus, const char **address) {
3423
3424 assert_return(bus, -EINVAL);
3425 assert_return(address, -EINVAL);
3426 assert_return(!bus_pid_changed(bus), -ECHILD);
3427
3428 if (bus->address) {
3429 *address = bus->address;
3430 return 0;
3acc1daf
LP
3431 }
3432
3433 return -ENODATA;
3434}
224b3787
LP
3435
3436int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *mask) {
3437 assert_return(bus, -EINVAL);
3438 assert_return(mask, -EINVAL);
3439 assert_return(!bus_pid_changed(bus), -ECHILD);
3440
3441 *mask = bus->creds_mask;
3442 return 0;
3443}
3444
3445int sd_bus_is_bus_client(sd_bus *bus) {
3446 assert_return(bus, -EINVAL);
3447 assert_return(!bus_pid_changed(bus), -ECHILD);
3448
3449 return bus->bus_client;
3450}
3451
3452int sd_bus_is_server(sd_bus *bus) {
3453 assert_return(bus, -EINVAL);
3454 assert_return(!bus_pid_changed(bus), -ECHILD);
3455
3456 return bus->is_server;
3457}
3458
3459int sd_bus_is_anonymous(sd_bus *bus) {
3460 assert_return(bus, -EINVAL);
3461 assert_return(!bus_pid_changed(bus), -ECHILD);
3462
3463 return bus->anonymous_auth;
3464}
3465
3466int sd_bus_is_trusted(sd_bus *bus) {
3467 assert_return(bus, -EINVAL);
3468 assert_return(!bus_pid_changed(bus), -ECHILD);
3469
3470 return bus->trusted;
3471}
3472
3473int sd_bus_is_monitor(sd_bus *bus) {
3474 assert_return(bus, -EINVAL);
3475 assert_return(!bus_pid_changed(bus), -ECHILD);
3476
3477 return !!(bus->hello_flags & KDBUS_HELLO_MONITOR);
3478}