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