]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/sd-bus.c
core: fix bus registration on daemon reexec
[thirdparty/systemd.git] / src / libsystemd-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"
de1c301e
LP
37
38#include "sd-bus.h"
39#include "bus-internal.h"
40#include "bus-message.h"
41#include "bus-type.h"
a7e3212d 42#include "bus-socket.h"
6629161f 43#include "bus-kernel.h"
392d5b37 44#include "bus-control.h"
29ddb38f
LP
45#include "bus-introspect.h"
46#include "bus-signature.h"
992c052c 47#include "bus-objects.h"
40ca29a1 48#include "bus-util.h"
a7893c6b 49#include "bus-container.h"
0461f8cd 50#include "bus-protocol.h"
de1c301e 51
e3017af9
LP
52static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
53
f54514f3
LP
54static void bus_close_fds(sd_bus *b) {
55 assert(b);
56
57 if (b->input_fd >= 0)
58 close_nointr_nofail(b->input_fd);
59
60 if (b->output_fd >= 0 && b->output_fd != b->input_fd)
61 close_nointr_nofail(b->output_fd);
62
63 b->input_fd = b->output_fd = -1;
64}
65
29ddb38f
LP
66static void bus_node_destroy(sd_bus *b, struct node *n) {
67 struct node_callback *c;
68 struct node_vtable *v;
69 struct node_enumerator *e;
70
71 assert(b);
72
73 if (!n)
74 return;
75
76 while (n->child)
77 bus_node_destroy(b, n->child);
78
79 while ((c = n->callbacks)) {
71fda00f 80 LIST_REMOVE(callbacks, n->callbacks, c);
29ddb38f
LP
81 free(c);
82 }
83
84 while ((v = n->vtables)) {
71fda00f 85 LIST_REMOVE(vtables, n->vtables, v);
29ddb38f
LP
86 free(v->interface);
87 free(v);
88 }
89
90 while ((e = n->enumerators)) {
71fda00f 91 LIST_REMOVE(enumerators, n->enumerators, e);
29ddb38f
LP
92 free(e);
93 }
94
95 if (n->parent)
71fda00f 96 LIST_REMOVE(siblings, n->parent->child, n);
29ddb38f
LP
97
98 assert_se(hashmap_remove(b->nodes, n->path) == n);
99 free(n->path);
100 free(n);
101}
102
0e586eae
LP
103static void bus_reset_queues(sd_bus *b) {
104 unsigned i;
105
106 assert(b);
107
108 for (i = 0; i < b->rqueue_size; i++)
109 sd_bus_message_unref(b->rqueue[i]);
110 free(b->rqueue);
111
112 for (i = 0; i < b->wqueue_size; i++)
113 sd_bus_message_unref(b->wqueue[i]);
114 free(b->wqueue);
115
116 b->rqueue = b->wqueue = NULL;
117 b->rqueue_size = b->wqueue_size = 0;
118}
119
de1c301e
LP
120static void bus_free(sd_bus *b) {
121 struct filter_callback *f;
29ddb38f 122 struct node *n;
de1c301e
LP
123
124 assert(b);
125
40ca29a1
LP
126 sd_bus_detach_event(b);
127
f54514f3 128 bus_close_fds(b);
de1c301e 129
63edf05e
LP
130 if (b->kdbus_buffer)
131 munmap(b->kdbus_buffer, KDBUS_POOL_SIZE);
132
de1c301e 133 free(b->rbuffer);
89ffcd2a 134 free(b->unique_name);
2181a7f5 135 free(b->auth_buffer);
89ffcd2a 136 free(b->address);
e9a967f9 137 free(b->kernel);
a7893c6b 138 free(b->machine);
89ffcd2a 139
2fd9ae2e
LP
140 free(b->exec_path);
141 strv_free(b->exec_argv);
142
2c93b4ef
LP
143 close_many(b->fds, b->n_fds);
144 free(b->fds);
145
0e586eae 146 bus_reset_queues(b);
de1c301e
LP
147
148 hashmap_free_free(b->reply_callbacks);
e3017af9 149 prioq_free(b->reply_callbacks_prioq);
de1c301e
LP
150
151 while ((f = b->filter_callbacks)) {
71fda00f 152 LIST_REMOVE(callbacks, b->filter_callbacks, f);
de1c301e
LP
153 free(f);
154 }
155
392d5b37
LP
156 bus_match_free(&b->match_callbacks);
157
29ddb38f
LP
158 hashmap_free_free(b->vtable_methods);
159 hashmap_free_free(b->vtable_properties);
160
161 while ((n = hashmap_first(b->nodes)))
162 bus_node_destroy(b, n);
163
164 hashmap_free(b->nodes);
165
bc7fd8cd
LP
166 bus_kernel_flush_memfd(b);
167
45fbe937
LP
168 assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
169
de1c301e
LP
170 free(b);
171}
172
d9f644e2 173_public_ int sd_bus_new(sd_bus **ret) {
de1c301e
LP
174 sd_bus *r;
175
d6888822 176 assert_return(ret, -EINVAL);
021a1e78 177
de1c301e
LP
178 r = new0(sd_bus, 1);
179 if (!r)
021a1e78 180 return -ENOMEM;
de1c301e 181
e4ee6e5c 182 r->n_ref = REFCNT_INIT;
e82c9509 183 r->input_fd = r->output_fd = -1;
de1c301e 184 r->message_version = 1;
3310dfd5 185 r->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
d21a7bb1
DM
186 r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
187 r->attach_flags |= KDBUS_ATTACH_NAMES;
d5a2b9a6 188 r->original_pid = getpid();
de1c301e 189
45fbe937
LP
190 assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
191
de1c301e
LP
192 /* We guarantee that wqueue always has space for at least one
193 * entry */
194 r->wqueue = new(sd_bus_message*, 1);
195 if (!r->wqueue) {
196 free(r);
021a1e78 197 return -ENOMEM;
de1c301e
LP
198 }
199
021a1e78
LP
200 *ret = r;
201 return 0;
202}
203
d9f644e2 204_public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
021a1e78
LP
205 char *a;
206
d6888822
LP
207 assert_return(bus, -EINVAL);
208 assert_return(bus->state == BUS_UNSET, -EPERM);
209 assert_return(address, -EINVAL);
210 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
211
212 a = strdup(address);
213 if (!a)
214 return -ENOMEM;
215
216 free(bus->address);
217 bus->address = a;
218
219 return 0;
220}
221
d9f644e2 222_public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
d6888822
LP
223 assert_return(bus, -EINVAL);
224 assert_return(bus->state == BUS_UNSET, -EPERM);
225 assert_return(input_fd >= 0, -EINVAL);
226 assert_return(output_fd >= 0, -EINVAL);
227 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 228
e82c9509
LP
229 bus->input_fd = input_fd;
230 bus->output_fd = output_fd;
021a1e78
LP
231 return 0;
232}
233
d9f644e2 234_public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
2fd9ae2e
LP
235 char *p, **a;
236
d6888822
LP
237 assert_return(bus, -EINVAL);
238 assert_return(bus->state == BUS_UNSET, -EPERM);
239 assert_return(path, -EINVAL);
240 assert_return(!strv_isempty(argv), -EINVAL);
241 assert_return(!bus_pid_changed(bus), -ECHILD);
2fd9ae2e
LP
242
243 p = strdup(path);
244 if (!p)
245 return -ENOMEM;
246
247 a = strv_copy(argv);
248 if (!a) {
249 free(p);
250 return -ENOMEM;
251 }
252
253 free(bus->exec_path);
254 strv_free(bus->exec_argv);
255
256 bus->exec_path = p;
257 bus->exec_argv = a;
258
259 return 0;
260}
261
d9f644e2 262_public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
d6888822
LP
263 assert_return(bus, -EINVAL);
264 assert_return(bus->state == BUS_UNSET, -EPERM);
265 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 266
94bbf1ba 267 bus->bus_client = !!b;
021a1e78
LP
268 return 0;
269}
270
d9f644e2 271_public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
d6888822
LP
272 assert_return(bus, -EINVAL);
273 assert_return(bus->state == BUS_UNSET, -EPERM);
274 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 275
264ad849
LP
276 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b);
277 return 0;
278}
279
f21326e6 280_public_ int sd_bus_negotiate_attach_timestamp(sd_bus *bus, int b) {
16be4368
KS
281 assert_return(bus, -EINVAL);
282 assert_return(bus->state == BUS_UNSET, -EPERM);
283 assert_return(!bus_pid_changed(bus), -ECHILD);
284
d21a7bb1 285 SET_FLAG(bus->attach_flags, KDBUS_ATTACH_TIMESTAMP, b);
16be4368
KS
286 return 0;
287}
288
5b12334d 289_public_ int sd_bus_negotiate_attach_creds(sd_bus *bus, uint64_t mask) {
16be4368 290 assert_return(bus, -EINVAL);
95c4fe82 291 assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL);
16be4368
KS
292 assert_return(bus->state == BUS_UNSET, -EPERM);
293 assert_return(!bus_pid_changed(bus), -ECHILD);
294
49b832c5 295 /* The well knowns we need unconditionally, so that matches can work */
3310dfd5 296 bus->creds_mask = mask | SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
49b832c5 297
3310dfd5 298 return kdbus_translate_attach_flags(bus->creds_mask, &bus->creds_mask);
021a1e78 299}
de1c301e 300
d9f644e2 301_public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
d6888822
LP
302 assert_return(bus, -EINVAL);
303 assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL);
304 assert_return(bus->state == BUS_UNSET, -EPERM);
305 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
306
307 bus->is_server = !!b;
98178d39 308 bus->server_id = server_id;
2181a7f5
LP
309 return 0;
310}
311
d9f644e2 312_public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
d6888822
LP
313 assert_return(bus, -EINVAL);
314 assert_return(bus->state == BUS_UNSET, -EPERM);
315 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
316
317 bus->anonymous_auth = !!b;
318 return 0;
319}
320
adacb957
LP
321_public_ int sd_bus_set_trusted(sd_bus *bus, int b) {
322 assert_return(bus, -EINVAL);
323 assert_return(bus->state == BUS_UNSET, -EPERM);
324 assert_return(!bus_pid_changed(bus), -ECHILD);
325
326 bus->trusted = !!b;
327 return 0;
328}
329
ebcf1f97 330static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
de1c301e
LP
331 const char *s;
332 int r;
333
334 assert(bus);
c99c09a2 335 assert(bus->state == BUS_HELLO || bus->state == BUS_CLOSING);
de1c301e
LP
336 assert(reply);
337
40ca29a1 338 r = sd_bus_message_get_errno(reply);
eb01ba5d
LP
339 if (r < 0)
340 return r;
40ca29a1
LP
341 if (r > 0)
342 return -r;
eb01ba5d 343
de1c301e
LP
344 r = sd_bus_message_read(reply, "s", &s);
345 if (r < 0)
346 return r;
347
dafb7591
LP
348 if (!service_name_is_valid(s) || s[0] != ':')
349 return -EBADMSG;
350
de1c301e
LP
351 bus->unique_name = strdup(s);
352 if (!bus->unique_name)
353 return -ENOMEM;
354
c99c09a2
LP
355 if (bus->state == BUS_HELLO)
356 bus->state = BUS_RUNNING;
dafb7591 357
de1c301e
LP
358 return 1;
359}
360
361static int bus_send_hello(sd_bus *bus) {
362 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
363 int r;
364
365 assert(bus);
366
6629161f 367 if (!bus->bus_client || bus->is_kernel)
021a1e78
LP
368 return 0;
369
de1c301e
LP
370 r = sd_bus_message_new_method_call(
371 bus,
372 "org.freedesktop.DBus",
373 "/",
374 "org.freedesktop.DBus",
375 "Hello",
376 &m);
377 if (r < 0)
378 return r;
379
c49b30a2 380 return sd_bus_call_async(bus, m, hello_callback, NULL, 0, &bus->hello_serial);
de1c301e
LP
381}
382
a7e3212d 383int bus_start_running(sd_bus *bus) {
de1c301e
LP
384 assert(bus);
385
f08838da 386 if (bus->bus_client && !bus->is_kernel) {
de1c301e 387 bus->state = BUS_HELLO;
e3017af9 388 return 1;
de1c301e
LP
389 }
390
391 bus->state = BUS_RUNNING;
e3017af9 392 return 1;
de1c301e
LP
393}
394
395static int parse_address_key(const char **p, const char *key, char **value) {
396 size_t l, n = 0;
397 const char *a;
398 char *r = NULL;
399
400 assert(p);
401 assert(*p);
de1c301e
LP
402 assert(value);
403
2fd9ae2e
LP
404 if (key) {
405 l = strlen(key);
406 if (strncmp(*p, key, l) != 0)
407 return 0;
de1c301e 408
2fd9ae2e
LP
409 if ((*p)[l] != '=')
410 return 0;
de1c301e 411
2fd9ae2e
LP
412 if (*value)
413 return -EINVAL;
de1c301e 414
2fd9ae2e
LP
415 a = *p + l + 1;
416 } else
417 a = *p;
418
419 while (*a != ';' && *a != ',' && *a != 0) {
de1c301e
LP
420 char c, *t;
421
422 if (*a == '%') {
423 int x, y;
424
425 x = unhexchar(a[1]);
426 if (x < 0) {
427 free(r);
428 return x;
429 }
430
431 y = unhexchar(a[2]);
432 if (y < 0) {
433 free(r);
434 return y;
435 }
436
de1c301e 437 c = (char) ((x << 4) | y);
89ffcd2a
LP
438 a += 3;
439 } else {
de1c301e 440 c = *a;
89ffcd2a
LP
441 a++;
442 }
de1c301e 443
89ffcd2a 444 t = realloc(r, n + 2);
de1c301e
LP
445 if (!t) {
446 free(r);
447 return -ENOMEM;
448 }
449
450 r = t;
451 r[n++] = c;
452 }
453
89ffcd2a
LP
454 if (!r) {
455 r = strdup("");
456 if (!r)
457 return -ENOMEM;
458 } else
459 r[n] = 0;
460
461 if (*a == ',')
462 a++;
463
de1c301e 464 *p = a;
2fd9ae2e
LP
465
466 free(*value);
de1c301e 467 *value = r;
2fd9ae2e 468
de1c301e
LP
469 return 1;
470}
471
472static void skip_address_key(const char **p) {
473 assert(p);
474 assert(*p);
475
89ffcd2a
LP
476 *p += strcspn(*p, ",");
477
478 if (**p == ',')
479 (*p) ++;
de1c301e
LP
480}
481
2fd9ae2e
LP
482static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
483 _cleanup_free_ char *path = NULL, *abstract = NULL;
484 size_t l;
de1c301e
LP
485 int r;
486
487 assert(b);
2fd9ae2e
LP
488 assert(p);
489 assert(*p);
490 assert(guid);
de1c301e 491
2fd9ae2e
LP
492 while (**p != 0 && **p != ';') {
493 r = parse_address_key(p, "guid", guid);
494 if (r < 0)
495 return r;
496 else if (r > 0)
497 continue;
de1c301e 498
2fd9ae2e
LP
499 r = parse_address_key(p, "path", &path);
500 if (r < 0)
501 return r;
502 else if (r > 0)
503 continue;
de1c301e 504
2fd9ae2e
LP
505 r = parse_address_key(p, "abstract", &abstract);
506 if (r < 0)
507 return r;
508 else if (r > 0)
509 continue;
de1c301e 510
2fd9ae2e
LP
511 skip_address_key(p);
512 }
de1c301e 513
2fd9ae2e
LP
514 if (!path && !abstract)
515 return -EINVAL;
de1c301e 516
2fd9ae2e
LP
517 if (path && abstract)
518 return -EINVAL;
519
520 if (path) {
521 l = strlen(path);
522 if (l > sizeof(b->sockaddr.un.sun_path))
523 return -E2BIG;
de1c301e 524
2fd9ae2e
LP
525 b->sockaddr.un.sun_family = AF_UNIX;
526 strncpy(b->sockaddr.un.sun_path, path, sizeof(b->sockaddr.un.sun_path));
527 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l;
528 } else if (abstract) {
529 l = strlen(abstract);
530 if (l > sizeof(b->sockaddr.un.sun_path) - 1)
531 return -E2BIG;
532
533 b->sockaddr.un.sun_family = AF_UNIX;
534 b->sockaddr.un.sun_path[0] = 0;
535 strncpy(b->sockaddr.un.sun_path+1, abstract, sizeof(b->sockaddr.un.sun_path)-1);
536 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
537 }
538
539 return 0;
540}
541
542static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
543 _cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
2fd9ae2e 544 int r;
b92bea5d
ZJS
545 struct addrinfo *result, hints = {
546 .ai_socktype = SOCK_STREAM,
547 .ai_flags = AI_ADDRCONFIG,
548 };
2fd9ae2e
LP
549
550 assert(b);
551 assert(p);
552 assert(*p);
553 assert(guid);
554
555 while (**p != 0 && **p != ';') {
556 r = parse_address_key(p, "guid", guid);
557 if (r < 0)
558 return r;
559 else if (r > 0)
560 continue;
561
562 r = parse_address_key(p, "host", &host);
563 if (r < 0)
564 return r;
565 else if (r > 0)
566 continue;
567
568 r = parse_address_key(p, "port", &port);
569 if (r < 0)
570 return r;
571 else if (r > 0)
572 continue;
573
574 r = parse_address_key(p, "family", &family);
575 if (r < 0)
576 return r;
577 else if (r > 0)
578 continue;
579
580 skip_address_key(p);
581 }
582
583 if (!host || !port)
584 return -EINVAL;
585
2fd9ae2e
LP
586 if (family) {
587 if (streq(family, "ipv4"))
588 hints.ai_family = AF_INET;
589 else if (streq(family, "ipv6"))
590 hints.ai_family = AF_INET6;
591 else
592 return -EINVAL;
593 }
594
595 r = getaddrinfo(host, port, &hints, &result);
596 if (r == EAI_SYSTEM)
597 return -errno;
598 else if (r != 0)
599 return -EADDRNOTAVAIL;
600
601 memcpy(&b->sockaddr, result->ai_addr, result->ai_addrlen);
602 b->sockaddr_size = result->ai_addrlen;
603
604 freeaddrinfo(result);
605
606 return 0;
607}
608
609static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
610 char *path = NULL;
611 unsigned n_argv = 0, j;
612 char **argv = NULL;
613 int r;
614
615 assert(b);
616 assert(p);
617 assert(*p);
618 assert(guid);
619
620 while (**p != 0 && **p != ';') {
621 r = parse_address_key(p, "guid", guid);
622 if (r < 0)
623 goto fail;
624 else if (r > 0)
625 continue;
626
627 r = parse_address_key(p, "path", &path);
628 if (r < 0)
629 goto fail;
630 else if (r > 0)
631 continue;
632
633 if (startswith(*p, "argv")) {
634 unsigned ul;
635
636 errno = 0;
637 ul = strtoul(*p + 4, (char**) p, 10);
8333c77e 638 if (errno > 0 || **p != '=' || ul > 256) {
2fd9ae2e
LP
639 r = -EINVAL;
640 goto fail;
641 }
642
643 (*p) ++;
644
645 if (ul >= n_argv) {
646 char **x;
647
648 x = realloc(argv, sizeof(char*) * (ul + 2));
649 if (!x) {
650 r = -ENOMEM;
651 goto fail;
652 }
653
654 memset(x + n_argv, 0, sizeof(char*) * (ul - n_argv + 2));
655
656 argv = x;
657 n_argv = ul + 1;
658 }
659
660 r = parse_address_key(p, NULL, argv + ul);
de1c301e 661 if (r < 0)
2fd9ae2e 662 goto fail;
de1c301e 663
2fd9ae2e 664 continue;
de1c301e
LP
665 }
666
2fd9ae2e
LP
667 skip_address_key(p);
668 }
de1c301e 669
5a0f6033
LP
670 if (!path) {
671 r = -EINVAL;
2fd9ae2e 672 goto fail;
5a0f6033 673 }
de1c301e 674
2fd9ae2e
LP
675 /* Make sure there are no holes in the array, with the
676 * exception of argv[0] */
677 for (j = 1; j < n_argv; j++)
678 if (!argv[j]) {
679 r = -EINVAL;
680 goto fail;
681 }
682
683 if (argv && argv[0] == NULL) {
684 argv[0] = strdup(path);
685 if (!argv[0]) {
686 r = -ENOMEM;
687 goto fail;
688 }
689 }
de1c301e 690
2fd9ae2e
LP
691 b->exec_path = path;
692 b->exec_argv = argv;
693 return 0;
de1c301e 694
2fd9ae2e
LP
695fail:
696 for (j = 0; j < n_argv; j++)
697 free(argv[j]);
698
699 free(argv);
700 free(path);
701 return r;
702}
703
6629161f
LP
704static int parse_kernel_address(sd_bus *b, const char **p, char **guid) {
705 _cleanup_free_ char *path = NULL;
706 int r;
707
708 assert(b);
709 assert(p);
710 assert(*p);
711 assert(guid);
712
713 while (**p != 0 && **p != ';') {
714 r = parse_address_key(p, "guid", guid);
715 if (r < 0)
716 return r;
717 else if (r > 0)
718 continue;
719
720 r = parse_address_key(p, "path", &path);
721 if (r < 0)
722 return r;
723 else if (r > 0)
724 continue;
725
726 skip_address_key(p);
727 }
728
729 if (!path)
730 return -EINVAL;
731
732 free(b->kernel);
733 b->kernel = path;
734 path = NULL;
735
736 return 0;
737}
738
a7893c6b
LP
739static int parse_container_address(sd_bus *b, const char **p, char **guid) {
740 _cleanup_free_ char *machine = NULL;
741 int r;
742
743 assert(b);
744 assert(p);
745 assert(*p);
746 assert(guid);
747
748 while (**p != 0 && **p != ';') {
749 r = parse_address_key(p, "guid", guid);
750 if (r < 0)
751 return r;
752 else if (r > 0)
753 continue;
754
755 r = parse_address_key(p, "machine", &machine);
756 if (r < 0)
757 return r;
758 else if (r > 0)
759 continue;
760
761 skip_address_key(p);
762 }
763
764 if (!machine)
765 return -EINVAL;
766
b6741478
LP
767 if (!filename_is_safe(machine))
768 return -EINVAL;
769
a7893c6b
LP
770 free(b->machine);
771 b->machine = machine;
772 machine = NULL;
773
774 b->sockaddr.un.sun_family = AF_UNIX;
775 strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
776 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + sizeof("/var/run/dbus/system_bus_socket") - 1;
777
778 return 0;
779}
780
2fd9ae2e
LP
781static void bus_reset_parsed_address(sd_bus *b) {
782 assert(b);
783
784 zero(b->sockaddr);
785 b->sockaddr_size = 0;
786 strv_free(b->exec_argv);
787 free(b->exec_path);
788 b->exec_path = NULL;
789 b->exec_argv = NULL;
98178d39 790 b->server_id = SD_ID128_NULL;
6629161f
LP
791 free(b->kernel);
792 b->kernel = NULL;
a7893c6b
LP
793 free(b->machine);
794 b->machine = NULL;
2fd9ae2e
LP
795}
796
797static int bus_parse_next_address(sd_bus *b) {
798 _cleanup_free_ char *guid = NULL;
799 const char *a;
800 int r;
801
802 assert(b);
803
804 if (!b->address)
805 return 0;
806 if (b->address[b->address_index] == 0)
807 return 0;
808
809 bus_reset_parsed_address(b);
810
811 a = b->address + b->address_index;
de1c301e 812
2fd9ae2e 813 while (*a != 0) {
de1c301e 814
2fd9ae2e
LP
815 if (*a == ';') {
816 a++;
817 continue;
de1c301e
LP
818 }
819
2fd9ae2e
LP
820 if (startswith(a, "unix:")) {
821 a += 5;
de1c301e 822
2fd9ae2e 823 r = parse_unix_address(b, &a, &guid);
de1c301e
LP
824 if (r < 0)
825 return r;
2fd9ae2e 826 break;
de1c301e 827
2fd9ae2e 828 } else if (startswith(a, "tcp:")) {
de1c301e 829
2fd9ae2e
LP
830 a += 4;
831 r = parse_tcp_address(b, &a, &guid);
de1c301e
LP
832 if (r < 0)
833 return r;
de1c301e 834
2fd9ae2e
LP
835 break;
836
837 } else if (startswith(a, "unixexec:")) {
838
839 a += 9;
840 r = parse_exec_address(b, &a, &guid);
de1c301e
LP
841 if (r < 0)
842 return r;
de1c301e 843
2fd9ae2e 844 break;
de1c301e 845
6629161f
LP
846 } else if (startswith(a, "kernel:")) {
847
848 a += 7;
849 r = parse_kernel_address(b, &a, &guid);
850 if (r < 0)
851 return r;
852
a7893c6b
LP
853 break;
854 } else if (startswith(a, "x-container:")) {
855
856 a += 12;
857 r = parse_container_address(b, &a, &guid);
858 if (r < 0)
859 return r;
860
6629161f 861 break;
de1c301e
LP
862 }
863
2fd9ae2e
LP
864 a = strchr(a, ';');
865 if (!a)
866 return 0;
de1c301e
LP
867 }
868
869 if (guid) {
98178d39 870 r = sd_id128_from_string(guid, &b->server_id);
de1c301e
LP
871 if (r < 0)
872 return r;
873 }
874
2fd9ae2e 875 b->address_index = a - b->address;
de1c301e
LP
876 return 1;
877}
878
a7e3212d 879static int bus_start_address(sd_bus *b) {
2fd9ae2e
LP
880 int r;
881
882 assert(b);
883
884 for (;;) {
e82c9509 885 sd_bus_close(b);
2fd9ae2e 886
a7893c6b 887 if (b->exec_path) {
a7e3212d 888
a7893c6b 889 r = bus_socket_exec(b);
2fd9ae2e
LP
890 if (r >= 0)
891 return r;
892
893 b->last_connect_error = -r;
a7893c6b 894 } else if (b->kernel) {
2fd9ae2e 895
a7893c6b
LP
896 r = bus_kernel_connect(b);
897 if (r >= 0)
898 return r;
2fd9ae2e 899
a7893c6b
LP
900 b->last_connect_error = -r;
901
902 } else if (b->machine) {
903
904 r = bus_container_connect(b);
2fd9ae2e
LP
905 if (r >= 0)
906 return r;
907
6629161f 908 b->last_connect_error = -r;
6629161f 909
a7893c6b
LP
910 } else if (b->sockaddr.sa.sa_family != AF_UNSPEC) {
911
912 r = bus_socket_connect(b);
6629161f
LP
913 if (r >= 0)
914 return r;
915
2fd9ae2e
LP
916 b->last_connect_error = -r;
917 }
918
919 r = bus_parse_next_address(b);
920 if (r < 0)
921 return r;
922 if (r == 0)
923 return b->last_connect_error ? -b->last_connect_error : -ECONNREFUSED;
de1c301e
LP
924 }
925}
926
a7e3212d
LP
927int bus_next_address(sd_bus *b) {
928 assert(b);
929
930 bus_reset_parsed_address(b);
931 return bus_start_address(b);
932}
933
021a1e78 934static int bus_start_fd(sd_bus *b) {
6629161f 935 struct stat st;
021a1e78
LP
936 int r;
937
938 assert(b);
e82c9509
LP
939 assert(b->input_fd >= 0);
940 assert(b->output_fd >= 0);
021a1e78 941
e82c9509 942 r = fd_nonblock(b->input_fd, true);
021a1e78
LP
943 if (r < 0)
944 return r;
945
e82c9509 946 r = fd_cloexec(b->input_fd, true);
021a1e78
LP
947 if (r < 0)
948 return r;
949
e82c9509
LP
950 if (b->input_fd != b->output_fd) {
951 r = fd_nonblock(b->output_fd, true);
952 if (r < 0)
953 return r;
954
955 r = fd_cloexec(b->output_fd, true);
956 if (r < 0)
957 return r;
958 }
959
6629161f
LP
960 if (fstat(b->input_fd, &st) < 0)
961 return -errno;
962
963 if (S_ISCHR(b->input_fd))
964 return bus_kernel_take_fd(b);
965 else
966 return bus_socket_take_fd(b);
021a1e78
LP
967}
968
d9f644e2 969_public_ int sd_bus_start(sd_bus *bus) {
021a1e78
LP
970 int r;
971
d6888822
LP
972 assert_return(bus, -EINVAL);
973 assert_return(bus->state == BUS_UNSET, -EPERM);
974 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
975
976 bus->state = BUS_OPENING;
977
2181a7f5
LP
978 if (bus->is_server && bus->bus_client)
979 return -EINVAL;
980
e82c9509 981 if (bus->input_fd >= 0)
021a1e78 982 r = bus_start_fd(bus);
a7893c6b 983 else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->kernel || bus->machine)
a7e3212d 984 r = bus_start_address(bus);
021a1e78
LP
985 else
986 return -EINVAL;
987
988 if (r < 0)
989 return r;
990
991 return bus_send_hello(bus);
992}
993
d9f644e2 994_public_ int sd_bus_open_system(sd_bus **ret) {
de1c301e
LP
995 const char *e;
996 sd_bus *b;
997 int r;
998
d6888822 999 assert_return(ret, -EINVAL);
de1c301e 1000
021a1e78
LP
1001 r = sd_bus_new(&b);
1002 if (r < 0)
1003 return r;
1004
6c03089c 1005 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
e3dd987c 1006 if (e)
021a1e78 1007 r = sd_bus_set_address(b, e);
e3dd987c 1008 else
626851be 1009#ifdef ENABLE_KDBUS
e3dd987c 1010 r = sd_bus_set_address(b, "kernel:path=/dev/kdbus/0-system/bus;unix:path=/run/dbus/system_bus_socket");
626851be
LP
1011#else
1012 r = sd_bus_set_address(b, "unix:path=/run/dbus/system_bus_socket");
1013#endif
e3dd987c
LP
1014
1015 if (r < 0)
1016 goto fail;
de1c301e 1017
94bbf1ba 1018 b->bus_client = true;
021a1e78 1019
adacb957
LP
1020 /* Let's do per-method access control on the system bus. We
1021 * need the caller's UID and capability set for that. */
1022 b->trusted = false;
1023 b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
1024
021a1e78
LP
1025 r = sd_bus_start(b);
1026 if (r < 0)
1027 goto fail;
de1c301e
LP
1028
1029 *ret = b;
1030 return 0;
021a1e78
LP
1031
1032fail:
1033 bus_free(b);
1034 return r;
de1c301e
LP
1035}
1036
d9f644e2 1037_public_ int sd_bus_open_user(sd_bus **ret) {
de1c301e
LP
1038 const char *e;
1039 sd_bus *b;
de1c301e
LP
1040 int r;
1041
d6888822 1042 assert_return(ret, -EINVAL);
de1c301e 1043
021a1e78
LP
1044 r = sd_bus_new(&b);
1045 if (r < 0)
1046 return r;
1047
6c03089c 1048 e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
de1c301e 1049 if (e) {
021a1e78 1050 r = sd_bus_set_address(b, e);
de1c301e 1051 if (r < 0)
021a1e78 1052 goto fail;
89ffcd2a 1053 } else {
6c03089c 1054 e = secure_getenv("XDG_RUNTIME_DIR");
e3dd987c
LP
1055 if (e) {
1056 _cleanup_free_ char *ee = NULL;
1057
1058 ee = bus_address_escape(e);
1059 if (!ee) {
626851be 1060 r = -ENOMEM;
e3dd987c
LP
1061 goto fail;
1062 }
1063
626851be 1064#ifdef ENABLE_KDBUS
e3dd987c 1065 asprintf(&b->address, "kernel:path=/dev/kdbus/%lu-user/bus;unix:path=%s/bus", (unsigned long) getuid(), ee);
626851be
LP
1066#else
1067 b->address = strjoin("unix:path=", ee, "/bus", NULL);
1068#endif
1069 } else {
1070#ifdef ENABLE_KDBUS
e3dd987c 1071 asprintf(&b->address, "kernel:path=/dev/kdbus/%lu-user/bus", (unsigned long) getuid());
626851be
LP
1072#else
1073 return -ECONNREFUSED;
1074#endif
1075 }
de1c301e 1076
e3dd987c
LP
1077 if (!b->address) {
1078 r = -ENOMEM;
021a1e78
LP
1079 goto fail;
1080 }
de1c301e
LP
1081 }
1082
94bbf1ba 1083 b->bus_client = true;
de1c301e 1084
adacb957
LP
1085 /* We don't do any per-method access control on the user
1086 * bus. */
1087 b->trusted = true;
1088
021a1e78 1089 r = sd_bus_start(b);
2571ead1
LP
1090 if (r < 0)
1091 goto fail;
de1c301e
LP
1092
1093 *ret = b;
1094 return 0;
2571ead1
LP
1095
1096fail:
021a1e78 1097 bus_free(b);
2571ead1 1098 return r;
de1c301e
LP
1099}
1100
d9f644e2 1101_public_ int sd_bus_open_system_remote(const char *host, sd_bus **ret) {
0f8bd8de
LP
1102 _cleanup_free_ char *e = NULL;
1103 char *p = NULL;
1104 sd_bus *bus;
1105 int r;
1106
1107 assert_return(host, -EINVAL);
1108 assert_return(ret, -EINVAL);
1109
1110 e = bus_address_escape(host);
1111 if (!e)
1112 return -ENOMEM;
1113
1114 p = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", NULL);
1115 if (!p)
1116 return -ENOMEM;
a7893c6b
LP
1117
1118 r = sd_bus_new(&bus);
1119 if (r < 0) {
1120 free(p);
1121 return r;
1122 }
1123
1124 bus->address = p;
1125 bus->bus_client = true;
1126
1127 r = sd_bus_start(bus);
1128 if (r < 0) {
1129 bus_free(bus);
1130 return r;
1131 }
1132
1133 *ret = bus;
1134 return 0;
1135}
1136
d9f644e2 1137_public_ int sd_bus_open_system_container(const char *machine, sd_bus **ret) {
a7893c6b
LP
1138 _cleanup_free_ char *e = NULL;
1139 sd_bus *bus;
1140 char *p;
1141 int r;
1142
1143 assert_return(machine, -EINVAL);
1144 assert_return(ret, -EINVAL);
9e554864 1145 assert_return(filename_is_safe(machine), -EINVAL);
a7893c6b
LP
1146
1147 e = bus_address_escape(machine);
1148 if (!e)
1149 return -ENOMEM;
1150
9e554864
LP
1151#ifdef ENABLE_KDBUS
1152 p = strjoin("kernel:path=/dev/kdbus/ns/machine-", e, "/0-system/bus;x-container:machine=", e, NULL);
1153#else
a7893c6b 1154 p = strjoin("x-container:machine=", e, NULL);
9e554864 1155#endif
a7893c6b
LP
1156 if (!p)
1157 return -ENOMEM;
0f8bd8de
LP
1158
1159 r = sd_bus_new(&bus);
1160 if (r < 0) {
1161 free(p);
1162 return r;
1163 }
1164
1165 bus->address = p;
1166 bus->bus_client = true;
1167
1168 r = sd_bus_start(bus);
1169 if (r < 0) {
1170 bus_free(bus);
1171 return r;
1172 }
1173
1174 *ret = bus;
1175 return 0;
1176}
1177
d9f644e2 1178_public_ void sd_bus_close(sd_bus *bus) {
0e586eae 1179
de1c301e
LP
1180 if (!bus)
1181 return;
d5a2b9a6
LP
1182 if (bus->state == BUS_CLOSED)
1183 return;
1184 if (bus_pid_changed(bus))
f54514f3
LP
1185 return;
1186
1187 bus->state = BUS_CLOSED;
e82c9509 1188
40ca29a1
LP
1189 sd_bus_detach_event(bus);
1190
0e586eae
LP
1191 /* Drop all queued messages so that they drop references to
1192 * the bus object and the bus may be freed */
1193 bus_reset_queues(bus);
1194
f54514f3
LP
1195 if (!bus->is_kernel)
1196 bus_close_fds(bus);
1197
1198 /* We'll leave the fd open in case this is a kernel bus, since
1199 * there might still be memblocks around that reference this
1d0e3c98
DM
1200 * bus, and they might need to invoke the * KDBUS_CMD_FREE
1201 * ioctl on the fd when they are freed. */
de1c301e
LP
1202}
1203
718db961
LP
1204static void bus_enter_closing(sd_bus *bus) {
1205 assert(bus);
1206
1207 if (bus->state != BUS_OPENING &&
1208 bus->state != BUS_AUTHENTICATING &&
1209 bus->state != BUS_HELLO &&
1210 bus->state != BUS_RUNNING)
1211 return;
1212
1213 bus->state = BUS_CLOSING;
1214}
1215
d9f644e2 1216_public_ sd_bus *sd_bus_ref(sd_bus *bus) {
9d6c7c82 1217 assert_return(bus, NULL);
de1c301e 1218
e4ee6e5c 1219 assert_se(REFCNT_INC(bus->n_ref) >= 2);
de1c301e 1220
de1c301e
LP
1221 return bus;
1222}
1223
d9f644e2 1224_public_ sd_bus *sd_bus_unref(sd_bus *bus) {
5b1bc83f
LP
1225
1226 if (!bus)
1227 return NULL;
de1c301e 1228
e4ee6e5c 1229 if (REFCNT_DEC(bus->n_ref) <= 0)
de1c301e
LP
1230 bus_free(bus);
1231
1232 return NULL;
1233}
1234
d9f644e2 1235_public_ int sd_bus_is_open(sd_bus *bus) {
d6888822
LP
1236
1237 assert_return(bus, -EINVAL);
1238 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 1239
f54514f3 1240 return BUS_IS_OPEN(bus->state);
e3017af9
LP
1241}
1242
d9f644e2 1243_public_ int sd_bus_can_send(sd_bus *bus, char type) {
d728d708
LP
1244 int r;
1245
d6888822
LP
1246 assert_return(bus, -EINVAL);
1247 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
1248 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1249
d728d708 1250 if (type == SD_BUS_TYPE_UNIX_FD) {
264ad849 1251 if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
021a1e78
LP
1252 return 0;
1253
20902f3e 1254 r = bus_ensure_running(bus);
d728d708
LP
1255 if (r < 0)
1256 return r;
de1c301e 1257
d728d708
LP
1258 return bus->can_fds;
1259 }
1260
1261 return bus_type_is_valid(type);
de1c301e
LP
1262}
1263
d9f644e2 1264_public_ int sd_bus_get_server_id(sd_bus *bus, sd_id128_t *server_id) {
d728d708 1265 int r;
de1c301e 1266
d6888822
LP
1267 assert_return(bus, -EINVAL);
1268 assert_return(server_id, -EINVAL);
1269 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1270
20902f3e 1271 r = bus_ensure_running(bus);
d728d708
LP
1272 if (r < 0)
1273 return r;
de1c301e 1274
98178d39 1275 *server_id = bus->server_id;
d728d708 1276 return 0;
de1c301e
LP
1277}
1278
7adc46fc
LP
1279static int bus_seal_message(sd_bus *b, sd_bus_message *m) {
1280 assert(b);
de1c301e
LP
1281 assert(m);
1282
89ffcd2a
LP
1283 if (m->header->version > b->message_version)
1284 return -EPERM;
1285
aea93deb
LP
1286 if (m->sealed) {
1287 /* If we copy the same message to multiple
1288 * destinations, avoid using the same serial
1289 * numbers. */
1290 b->serial = MAX(b->serial, BUS_MESSAGE_SERIAL(m));
de1c301e 1291 return 0;
aea93deb 1292 }
de1c301e 1293
9a17484d 1294 return bus_message_seal(m, ++b->serial);
de1c301e
LP
1295}
1296
7adc46fc
LP
1297int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
1298 assert(b);
1299 assert(m);
1300
1301 if (m->header->version > b->message_version)
1302 return -EPERM;
1303
1304 /* The bus specification says the serial number cannot be 0,
1305 * hence let's fill something in for synthetic messages. Since
1306 * synthetic messages might have a fake sender and we don't
1307 * want to interfere with the real sender's serial numbers we
1308 * pick a fixed, artifical one. We use (uint32_t) -1 rather
1309 * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
1310 * even though kdbus can do 64bit. */
1311
1312 return bus_message_seal(m, 0xFFFFFFFFULL);
1313}
1314
718db961 1315static int bus_write_message(sd_bus *bus, sd_bus_message *message, size_t *idx) {
718db961
LP
1316 assert(bus);
1317 assert(message);
1318
1319 if (bus->is_kernel)
a43b9ca3 1320 return bus_kernel_write_message(bus, message);
718db961 1321 else
a43b9ca3 1322 return bus_socket_write_message(bus, message, idx);
718db961
LP
1323}
1324
de1c301e 1325static int dispatch_wqueue(sd_bus *bus) {
e3017af9 1326 int r, ret = 0;
de1c301e
LP
1327
1328 assert(bus);
89ffcd2a 1329 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1330
de1c301e
LP
1331 while (bus->wqueue_size > 0) {
1332
718db961
LP
1333 r = bus_write_message(bus, bus->wqueue[0], &bus->windex);
1334 if (r < 0)
de1c301e 1335 return r;
718db961 1336 else if (r == 0)
e3017af9
LP
1337 /* Didn't do anything this time */
1338 return ret;
6629161f 1339 else if (bus->is_kernel || bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
de1c301e
LP
1340 /* Fully written. Let's drop the entry from
1341 * the queue.
1342 *
1343 * This isn't particularly optimized, but
1344 * well, this is supposed to be our worst-case
1345 * buffer only, and the socket buffer is
1346 * supposed to be our primary buffer, and if
1347 * it got full, then all bets are off
1348 * anyway. */
1349
1350 sd_bus_message_unref(bus->wqueue[0]);
1351 bus->wqueue_size --;
1352 memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
1353 bus->windex = 0;
1354
e3017af9 1355 ret = 1;
de1c301e
LP
1356 }
1357 }
1358
e3017af9 1359 return ret;
de1c301e
LP
1360}
1361
7d22c717
LP
1362static int bus_read_message(sd_bus *bus) {
1363 assert(bus);
1364
1365 if (bus->is_kernel)
1366 return bus_kernel_read_message(bus);
1367 else
1368 return bus_socket_read_message(bus);
1369}
1370
7adc46fc 1371int bus_rqueue_make_room(sd_bus *bus) {
7d22c717
LP
1372 sd_bus_message **q;
1373 unsigned x;
1374
7adc46fc 1375 x = bus->rqueue_size + 1;
7d22c717
LP
1376
1377 if (bus->rqueue_allocated >= x)
1378 return 0;
1379
1380 if (x > BUS_RQUEUE_MAX)
1381 return -ENOBUFS;
1382
1383 q = realloc(bus->rqueue, x * sizeof(sd_bus_message*));
1384 if (!q)
1385 return -ENOMEM;
1386
1387 bus->rqueue = q;
1388 bus->rqueue_allocated = x;
1389
1390 return 0;
1391}
1392
de1c301e 1393static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) {
e3017af9 1394 int r, ret = 0;
de1c301e
LP
1395
1396 assert(bus);
1397 assert(m);
89ffcd2a 1398 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1399
7d22c717
LP
1400 for (;;) {
1401 if (bus->rqueue_size > 0) {
1402 /* Dispatch a queued message */
de1c301e 1403
7d22c717
LP
1404 *m = bus->rqueue[0];
1405 bus->rqueue_size --;
1406 memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
1407 return 1;
1408 }
de1c301e 1409
7d22c717
LP
1410 /* Try to read a new message */
1411 r = bus_read_message(bus);
718db961 1412 if (r < 0)
e3017af9 1413 return r;
e3017af9
LP
1414 if (r == 0)
1415 return ret;
de1c301e 1416
2e8d788c 1417 ret = 1;
7d22c717 1418 }
de1c301e
LP
1419}
1420
d9f644e2 1421_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
de1c301e
LP
1422 int r;
1423
d6888822
LP
1424 assert_return(bus, -EINVAL);
1425 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1426 assert_return(m, -EINVAL);
1427 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
1428
1429 if (m->n_fds > 0) {
1430 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1431 if (r < 0)
1432 return r;
1433 if (r == 0)
1434 return -ENOTSUP;
1435 }
de1c301e 1436
29f6aadd
LP
1437 /* If the serial number isn't kept, then we know that no reply
1438 * is expected */
1439 if (!serial && !m->sealed)
0461f8cd 1440 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
29f6aadd 1441
de1c301e
LP
1442 r = bus_seal_message(bus, m);
1443 if (r < 0)
1444 return r;
1445
5407f2de
LP
1446 /* If this is a reply and no reply was requested, then let's
1447 * suppress this, if we can */
1448 if (m->dont_send && !serial)
7a37d625 1449 return 1;
5407f2de 1450
89ffcd2a 1451 if ((bus->state == BUS_RUNNING || bus->state == BUS_HELLO) && bus->wqueue_size <= 0) {
de1c301e
LP
1452 size_t idx = 0;
1453
718db961 1454 r = bus_write_message(bus, m, &idx);
32f46480
LP
1455 if (r < 0) {
1456 if (r == -EPIPE || r == -ENOTCONN || r == -ESHUTDOWN)
1457 bus_enter_closing(bus);
1458
de1c301e 1459 return r;
32f46480 1460 } else if (!bus->is_kernel && idx < BUS_MESSAGE_SIZE(m)) {
de1c301e
LP
1461 /* Wasn't fully written. So let's remember how
1462 * much was written. Note that the first entry
1463 * of the wqueue array is always allocated so
1464 * that we always can remember how much was
1465 * written. */
1466 bus->wqueue[0] = sd_bus_message_ref(m);
1467 bus->wqueue_size = 1;
1468 bus->windex = idx;
1469 }
1470 } else {
1471 sd_bus_message **q;
1472
1473 /* Just append it to the queue. */
1474
25220239 1475 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
de1c301e
LP
1476 return -ENOBUFS;
1477
1478 q = realloc(bus->wqueue, sizeof(sd_bus_message*) * (bus->wqueue_size + 1));
1479 if (!q)
1480 return -ENOMEM;
1481
1482 bus->wqueue = q;
1483 q[bus->wqueue_size ++] = sd_bus_message_ref(m);
1484 }
1485
1486 if (serial)
1487 *serial = BUS_MESSAGE_SERIAL(m);
1488
7a37d625 1489 return 1;
de1c301e
LP
1490}
1491
911121a7
LP
1492_public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *serial) {
1493 int r;
1494
1495 assert_return(bus, -EINVAL);
1496 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1497 assert_return(m, -EINVAL);
1498 assert_return(!bus_pid_changed(bus), -ECHILD);
1499
1500 if (!streq_ptr(m->destination, destination)) {
1501
1502 if (!destination)
1503 return -EEXIST;
1504
1505 r = sd_bus_message_set_destination(m, destination);
1506 if (r < 0)
1507 return r;
1508 }
1509
1510 return sd_bus_send(bus, m, serial);
1511}
1512
de1c301e
LP
1513static usec_t calc_elapse(uint64_t usec) {
1514 if (usec == (uint64_t) -1)
1515 return 0;
1516
1517 if (usec == 0)
e3017af9 1518 usec = BUS_DEFAULT_TIMEOUT;
de1c301e
LP
1519
1520 return now(CLOCK_MONOTONIC) + usec;
1521}
1522
e3017af9
LP
1523static int timeout_compare(const void *a, const void *b) {
1524 const struct reply_callback *x = a, *y = b;
1525
1526 if (x->timeout != 0 && y->timeout == 0)
1527 return -1;
1528
1529 if (x->timeout == 0 && y->timeout != 0)
1530 return 1;
1531
1532 if (x->timeout < y->timeout)
1533 return -1;
1534
1535 if (x->timeout > y->timeout)
1536 return 1;
1537
1538 return 0;
1539}
1540
c49b30a2 1541_public_ int sd_bus_call_async(
de1c301e
LP
1542 sd_bus *bus,
1543 sd_bus_message *m,
52f3ba91 1544 sd_bus_message_handler_t callback,
de1c301e
LP
1545 void *userdata,
1546 uint64_t usec,
1547 uint64_t *serial) {
1548
1549 struct reply_callback *c;
1550 int r;
1551
d6888822
LP
1552 assert_return(bus, -EINVAL);
1553 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1554 assert_return(m, -EINVAL);
40ca29a1 1555 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
0461f8cd 1556 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
d6888822
LP
1557 assert_return(callback, -EINVAL);
1558 assert_return(!bus_pid_changed(bus), -ECHILD);
89ffcd2a
LP
1559
1560 r = hashmap_ensure_allocated(&bus->reply_callbacks, uint64_hash_func, uint64_compare_func);
1561 if (r < 0)
1562 return r;
de1c301e 1563
e3017af9
LP
1564 if (usec != (uint64_t) -1) {
1565 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1566 if (r < 0)
1567 return r;
1568 }
1569
de1c301e
LP
1570 r = bus_seal_message(bus, m);
1571 if (r < 0)
1572 return r;
1573
eba8617e 1574 c = new0(struct reply_callback, 1);
de1c301e
LP
1575 if (!c)
1576 return -ENOMEM;
1577
1578 c->callback = callback;
1579 c->userdata = userdata;
1580 c->serial = BUS_MESSAGE_SERIAL(m);
1581 c->timeout = calc_elapse(usec);
1582
1583 r = hashmap_put(bus->reply_callbacks, &c->serial, c);
1584 if (r < 0) {
1585 free(c);
1586 return r;
1587 }
1588
e3017af9
LP
1589 if (c->timeout != 0) {
1590 r = prioq_put(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1591 if (r < 0) {
1592 c->timeout = 0;
c49b30a2 1593 sd_bus_call_async_cancel(bus, c->serial);
e3017af9
LP
1594 return r;
1595 }
1596 }
1597
de1c301e
LP
1598 r = sd_bus_send(bus, m, serial);
1599 if (r < 0) {
c49b30a2 1600 sd_bus_call_async_cancel(bus, c->serial);
de1c301e
LP
1601 return r;
1602 }
1603
1604 return r;
1605}
1606
c49b30a2 1607_public_ int sd_bus_call_async_cancel(sd_bus *bus, uint64_t serial) {
e3017af9 1608 struct reply_callback *c;
de1c301e 1609
d6888822
LP
1610 assert_return(bus, -EINVAL);
1611 assert_return(serial != 0, -EINVAL);
1612 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e
LP
1613
1614 c = hashmap_remove(bus->reply_callbacks, &serial);
1615 if (!c)
1616 return 0;
1617
e3017af9
LP
1618 if (c->timeout != 0)
1619 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1620
de1c301e
LP
1621 free(c);
1622 return 1;
1623}
1624
20902f3e 1625int bus_ensure_running(sd_bus *bus) {
89ffcd2a
LP
1626 int r;
1627
1628 assert(bus);
1629
718db961 1630 if (bus->state == BUS_UNSET || bus->state == BUS_CLOSED || bus->state == BUS_CLOSING)
021a1e78 1631 return -ENOTCONN;
d728d708
LP
1632 if (bus->state == BUS_RUNNING)
1633 return 1;
89ffcd2a
LP
1634
1635 for (;;) {
1636 r = sd_bus_process(bus, NULL);
1637 if (r < 0)
1638 return r;
d728d708
LP
1639 if (bus->state == BUS_RUNNING)
1640 return 1;
e3017af9
LP
1641 if (r > 0)
1642 continue;
89ffcd2a
LP
1643
1644 r = sd_bus_wait(bus, (uint64_t) -1);
1645 if (r < 0)
1646 return r;
1647 }
1648}
1649
c49b30a2 1650_public_ int sd_bus_call(
de1c301e
LP
1651 sd_bus *bus,
1652 sd_bus_message *m,
1653 uint64_t usec,
1654 sd_bus_error *error,
1655 sd_bus_message **reply) {
1656
de1c301e
LP
1657 usec_t timeout;
1658 uint64_t serial;
7d22c717
LP
1659 unsigned i;
1660 int r;
de1c301e 1661
d6888822
LP
1662 assert_return(bus, -EINVAL);
1663 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1664 assert_return(m, -EINVAL);
40ca29a1 1665 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
0461f8cd 1666 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
d6888822
LP
1667 assert_return(!bus_error_is_dirty(error), -EINVAL);
1668 assert_return(!bus_pid_changed(bus), -ECHILD);
89ffcd2a 1669
20902f3e 1670 r = bus_ensure_running(bus);
89ffcd2a
LP
1671 if (r < 0)
1672 return r;
de1c301e 1673
a43b9ca3
LP
1674 i = bus->rqueue_size;
1675
de1c301e
LP
1676 r = sd_bus_send(bus, m, &serial);
1677 if (r < 0)
1678 return r;
1679
1680 timeout = calc_elapse(usec);
1681
1682 for (;;) {
1683 usec_t left;
de1c301e 1684
7d22c717
LP
1685 while (i < bus->rqueue_size) {
1686 sd_bus_message *incoming = NULL;
1687
1688 incoming = bus->rqueue[i];
89ffcd2a 1689
de1c301e
LP
1690 if (incoming->reply_serial == serial) {
1691 /* Found a match! */
1692
7d22c717
LP
1693 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1694 bus->rqueue_size--;
1695
40ca29a1 1696 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
b7f247e0
LP
1697
1698 if (reply)
1699 *reply = incoming;
1700 else
1701 sd_bus_message_unref(incoming);
1702
7a37d625 1703 return 1;
a43b9ca3 1704 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
de1c301e 1705 r = sd_bus_error_copy(error, &incoming->error);
a43b9ca3
LP
1706 else
1707 r = -EIO;
de1c301e
LP
1708
1709 sd_bus_message_unref(incoming);
a43b9ca3 1710 return r;
a8a07f89
LP
1711
1712 } else if (incoming->header->serial == serial &&
1713 bus->unique_name &&
1714 incoming->sender &&
1715 streq(bus->unique_name, incoming->sender)) {
1716
7d22c717
LP
1717 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1718 bus->rqueue_size--;
1719
a8a07f89
LP
1720 /* Our own message? Somebody is trying
1721 * to send its own client a message,
1722 * let's not dead-lock, let's fail
1723 * immediately. */
1724
1725 sd_bus_message_unref(incoming);
1726 return -ELOOP;
de1c301e
LP
1727 }
1728
de1c301e 1729 /* Try to read more, right-away */
7d22c717 1730 i++;
de1c301e 1731 }
7d22c717 1732
a43b9ca3 1733 r = bus_read_message(bus);
32f46480
LP
1734 if (r < 0) {
1735 if (r == -EPIPE || r == -ENOTCONN || r == -ESHUTDOWN)
1736 bus_enter_closing(bus);
1737
a43b9ca3 1738 return r;
32f46480 1739 }
7d22c717 1740 if (r > 0)
e3017af9 1741 continue;
de1c301e
LP
1742
1743 if (timeout > 0) {
1744 usec_t n;
1745
1746 n = now(CLOCK_MONOTONIC);
1747 if (n >= timeout)
1748 return -ETIMEDOUT;
1749
1750 left = timeout - n;
1751 } else
1752 left = (uint64_t) -1;
1753
e3017af9 1754 r = bus_poll(bus, true, left);
de1c301e
LP
1755 if (r < 0)
1756 return r;
1757
1758 r = dispatch_wqueue(bus);
32f46480
LP
1759 if (r < 0) {
1760 if (r == -EPIPE || r == -ENOTCONN || r == -ESHUTDOWN)
1761 bus_enter_closing(bus);
1762
de1c301e 1763 return r;
32f46480 1764 }
de1c301e
LP
1765 }
1766}
1767
d9f644e2 1768_public_ int sd_bus_get_fd(sd_bus *bus) {
d6888822
LP
1769
1770 assert_return(bus, -EINVAL);
d6888822
LP
1771 assert_return(bus->input_fd == bus->output_fd, -EPERM);
1772 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1773
e82c9509 1774 return bus->input_fd;
de1c301e
LP
1775}
1776
d9f644e2 1777_public_ int sd_bus_get_events(sd_bus *bus) {
de1c301e
LP
1778 int flags = 0;
1779
d6888822 1780 assert_return(bus, -EINVAL);
718db961 1781 assert_return(BUS_IS_OPEN(bus->state) || bus->state == BUS_CLOSING, -ENOTCONN);
d6888822 1782 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e
LP
1783
1784 if (bus->state == BUS_OPENING)
1785 flags |= POLLOUT;
89ffcd2a
LP
1786 else if (bus->state == BUS_AUTHENTICATING) {
1787
2181a7f5 1788 if (bus_socket_auth_needs_write(bus))
89ffcd2a
LP
1789 flags |= POLLOUT;
1790
1791 flags |= POLLIN;
1792
1793 } else if (bus->state == BUS_RUNNING || bus->state == BUS_HELLO) {
de1c301e
LP
1794 if (bus->rqueue_size <= 0)
1795 flags |= POLLIN;
1796 if (bus->wqueue_size > 0)
1797 flags |= POLLOUT;
1798 }
1799
1800 return flags;
1801}
1802
d9f644e2 1803_public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
e3017af9
LP
1804 struct reply_callback *c;
1805
d6888822
LP
1806 assert_return(bus, -EINVAL);
1807 assert_return(timeout_usec, -EINVAL);
718db961 1808 assert_return(BUS_IS_OPEN(bus->state) || bus->state == BUS_CLOSING, -ENOTCONN);
d6888822 1809 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 1810
718db961
LP
1811 if (bus->state == BUS_CLOSING) {
1812 *timeout_usec = 0;
1813 return 1;
1814 }
1815
e3017af9
LP
1816 if (bus->state == BUS_AUTHENTICATING) {
1817 *timeout_usec = bus->auth_timeout;
1818 return 1;
1819 }
1820
adee69fa
LP
1821 if (bus->state != BUS_RUNNING && bus->state != BUS_HELLO) {
1822 *timeout_usec = (uint64_t) -1;
e3017af9 1823 return 0;
adee69fa 1824 }
e3017af9 1825
8efd6381
LP
1826 if (bus->rqueue_size > 0) {
1827 *timeout_usec = 0;
1828 return 1;
1829 }
1830
e3017af9 1831 c = prioq_peek(bus->reply_callbacks_prioq);
adee69fa
LP
1832 if (!c) {
1833 *timeout_usec = (uint64_t) -1;
e3017af9 1834 return 0;
adee69fa 1835 }
e3017af9
LP
1836
1837 *timeout_usec = c->timeout;
1838 return 1;
1839}
1840
1841static int process_timeout(sd_bus *bus) {
ebcf1f97 1842 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
eb01ba5d 1843 _cleanup_bus_message_unref_ sd_bus_message* m = NULL;
e3017af9
LP
1844 struct reply_callback *c;
1845 usec_t n;
1846 int r;
1847
1848 assert(bus);
1849
1850 c = prioq_peek(bus->reply_callbacks_prioq);
1851 if (!c)
1852 return 0;
1853
1854 n = now(CLOCK_MONOTONIC);
1855 if (c->timeout > n)
1856 return 0;
1857
eb01ba5d
LP
1858 r = bus_message_new_synthetic_error(
1859 bus,
1860 c->serial,
14c24659 1861 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
eb01ba5d
LP
1862 &m);
1863 if (r < 0)
1864 return r;
1865
34a2c9e8
LP
1866 m->sender = "org.freedesktop.DBus";
1867
7adc46fc 1868 r = bus_seal_synthetic_message(bus, m);
718db961
LP
1869 if (r < 0)
1870 return r;
1871
e3017af9
LP
1872 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
1873 hashmap_remove(bus->reply_callbacks, &c->serial);
1874
718db961
LP
1875 bus->current = m;
1876 bus->iteration_counter ++;
1877
ebcf1f97
LP
1878 r = c->callback(bus, m, c->userdata, &error_buffer);
1879 r = bus_maybe_reply_error(m, r, &error_buffer);
e3017af9
LP
1880 free(c);
1881
718db961
LP
1882 bus->current = NULL;
1883
ebcf1f97 1884 return r;
e3017af9
LP
1885}
1886
9d373862
LP
1887static int process_hello(sd_bus *bus, sd_bus_message *m) {
1888 assert(bus);
1889 assert(m);
1890
1891 if (bus->state != BUS_HELLO)
1892 return 0;
1893
1894 /* Let's make sure the first message on the bus is the HELLO
1895 * reply. But note that we don't actually parse the message
2181a7f5
LP
1896 * here (we leave that to the usual handling), we just verify
1897 * we don't let any earlier msg through. */
9d373862 1898
40ca29a1
LP
1899 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
1900 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
9d373862
LP
1901 return -EIO;
1902
1903 if (m->reply_serial != bus->hello_serial)
1904 return -EIO;
1905
1906 return 0;
1907}
1908
a652755d 1909static int process_reply(sd_bus *bus, sd_bus_message *m) {
ebcf1f97 1910 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
a652755d
LP
1911 struct reply_callback *c;
1912 int r;
1913
1914 assert(bus);
1915 assert(m);
1916
40ca29a1
LP
1917 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
1918 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
a652755d
LP
1919 return 0;
1920
1921 c = hashmap_remove(bus->reply_callbacks, &m->reply_serial);
1922 if (!c)
1923 return 0;
1924
1925 if (c->timeout != 0)
1926 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1927
88fe224c
LP
1928 r = sd_bus_message_rewind(m, true);
1929 if (r < 0)
1930 return r;
1931
ebcf1f97
LP
1932 r = c->callback(bus, m, c->userdata, &error_buffer);
1933 r = bus_maybe_reply_error(m, r, &error_buffer);
a652755d
LP
1934 free(c);
1935
ebcf1f97 1936 return r;
a652755d
LP
1937}
1938
1939static int process_filter(sd_bus *bus, sd_bus_message *m) {
ebcf1f97 1940 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
a652755d
LP
1941 struct filter_callback *l;
1942 int r;
1943
392d5b37
LP
1944 assert(bus);
1945 assert(m);
1946
7286037f
LP
1947 do {
1948 bus->filter_callbacks_modified = false;
1949
1950 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
1951
1952 if (bus->filter_callbacks_modified)
1953 break;
1954
1955 /* Don't run this more than once per iteration */
1956 if (l->last_iteration == bus->iteration_counter)
1957 continue;
1958
1959 l->last_iteration = bus->iteration_counter;
1960
88fe224c
LP
1961 r = sd_bus_message_rewind(m, true);
1962 if (r < 0)
1963 return r;
1964
969987ea 1965 r = l->callback(bus, m, l->userdata, &error_buffer);
ebcf1f97 1966 r = bus_maybe_reply_error(m, r, &error_buffer);
7286037f
LP
1967 if (r != 0)
1968 return r;
1969
1970 }
1971
1972 } while (bus->filter_callbacks_modified);
a652755d
LP
1973
1974 return 0;
1975}
1976
392d5b37 1977static int process_match(sd_bus *bus, sd_bus_message *m) {
7286037f
LP
1978 int r;
1979
392d5b37
LP
1980 assert(bus);
1981 assert(m);
1982
7286037f
LP
1983 do {
1984 bus->match_callbacks_modified = false;
1985
eb01ba5d 1986 r = bus_match_run(bus, &bus->match_callbacks, m);
7286037f
LP
1987 if (r != 0)
1988 return r;
1989
1990 } while (bus->match_callbacks_modified);
1991
1992 return 0;
392d5b37
LP
1993}
1994
b9bf7e2b
LP
1995static int process_builtin(sd_bus *bus, sd_bus_message *m) {
1996 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1997 int r;
1998
1999 assert(bus);
2000 assert(m);
2001
40ca29a1 2002 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
b9bf7e2b
LP
2003 return 0;
2004
2005 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
2006 return 0;
2007
0461f8cd 2008 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
b9bf7e2b
LP
2009 return 1;
2010
2011 if (streq_ptr(m->member, "Ping"))
df2d202e 2012 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2013 else if (streq_ptr(m->member, "GetMachineId")) {
2014 sd_id128_t id;
2015 char sid[33];
2016
2017 r = sd_id128_get_machine(&id);
2018 if (r < 0)
2019 return r;
2020
df2d202e 2021 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2022 if (r < 0)
2023 return r;
2024
2025 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
2026 } else {
29ddb38f 2027 r = sd_bus_message_new_method_errorf(
df2d202e 2028 m, &reply,
40ca29a1 2029 SD_BUS_ERROR_UNKNOWN_METHOD,
b9bf7e2b 2030 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
b9bf7e2b
LP
2031 }
2032
2033 if (r < 0)
2034 return r;
2035
2036 r = sd_bus_send(bus, reply, NULL);
2037 if (r < 0)
2038 return r;
2039
2040 return 1;
2041}
2042
992c052c 2043static int process_message(sd_bus *bus, sd_bus_message *m) {
e3017af9
LP
2044 int r;
2045
2046 assert(bus);
992c052c 2047 assert(m);
e3017af9 2048
affff0b6 2049 bus->current = m;
992c052c 2050 bus->iteration_counter++;
e3017af9 2051
40ca29a1
LP
2052 log_debug("Got message sender=%s object=%s interface=%s member=%s",
2053 strna(sd_bus_message_get_sender(m)),
2054 strna(sd_bus_message_get_path(m)),
2055 strna(sd_bus_message_get_interface(m)),
2056 strna(sd_bus_message_get_member(m)));
2057
992c052c
LP
2058 r = process_hello(bus, m);
2059 if (r != 0)
affff0b6 2060 goto finish;
a652755d 2061
992c052c
LP
2062 r = process_reply(bus, m);
2063 if (r != 0)
affff0b6 2064 goto finish;
e3017af9 2065
992c052c
LP
2066 r = process_filter(bus, m);
2067 if (r != 0)
affff0b6 2068 goto finish;
a652755d 2069
992c052c
LP
2070 r = process_match(bus, m);
2071 if (r != 0)
affff0b6 2072 goto finish;
a652755d 2073
992c052c
LP
2074 r = process_builtin(bus, m);
2075 if (r != 0)
affff0b6
LP
2076 goto finish;
2077
2078 r = bus_process_object(bus, m);
a652755d 2079
affff0b6
LP
2080finish:
2081 bus->current = NULL;
2082 return r;
29ddb38f 2083}
88fe224c 2084
992c052c
LP
2085static int process_running(sd_bus *bus, sd_bus_message **ret) {
2086 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
29ddb38f 2087 int r;
a652755d 2088
29ddb38f 2089 assert(bus);
992c052c 2090 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
7286037f 2091
992c052c
LP
2092 r = process_timeout(bus);
2093 if (r != 0)
2094 goto null_message;
7286037f 2095
992c052c
LP
2096 r = dispatch_wqueue(bus);
2097 if (r != 0)
2098 goto null_message;
7286037f 2099
992c052c
LP
2100 r = dispatch_rqueue(bus, &m);
2101 if (r < 0)
2102 return r;
2103 if (!m)
2104 goto null_message;
7286037f 2105
992c052c
LP
2106 r = process_message(bus, m);
2107 if (r != 0)
2108 goto null_message;
7286037f 2109
992c052c
LP
2110 if (ret) {
2111 r = sd_bus_message_rewind(m, true);
29ddb38f
LP
2112 if (r < 0)
2113 return r;
e3017af9 2114
992c052c
LP
2115 *ret = m;
2116 m = NULL;
2117 return 1;
2118 }
a652755d 2119
40ca29a1 2120 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
a652755d 2121
992c052c 2122 r = sd_bus_reply_method_errorf(
df2d202e 2123 m,
40ca29a1 2124 SD_BUS_ERROR_UNKNOWN_OBJECT,
992c052c 2125 "Unknown object '%s'.", m->path);
29ddb38f
LP
2126 if (r < 0)
2127 return r;
2128 }
e3017af9 2129
992c052c 2130 return 1;
0a72c2bd 2131
992c052c
LP
2132null_message:
2133 if (r >= 0 && ret)
2134 *ret = NULL;
0a72c2bd 2135
992c052c 2136 return r;
29ddb38f 2137}
0a72c2bd 2138
718db961
LP
2139static int process_closing(sd_bus *bus, sd_bus_message **ret) {
2140 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2141 struct reply_callback *c;
2142 int r;
2143
2144 assert(bus);
2145 assert(bus->state == BUS_CLOSING);
2146
2147 c = hashmap_first(bus->reply_callbacks);
2148 if (c) {
ebcf1f97
LP
2149 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2150
718db961
LP
2151 /* First, fail all outstanding method calls */
2152 r = bus_message_new_synthetic_error(
2153 bus,
2154 c->serial,
14c24659 2155 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
718db961
LP
2156 &m);
2157 if (r < 0)
2158 return r;
2159
7adc46fc 2160 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2161 if (r < 0)
2162 return r;
2163
2164 if (c->timeout != 0)
2165 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2166
2167 hashmap_remove(bus->reply_callbacks, &c->serial);
2168
2169 bus->current = m;
2170 bus->iteration_counter++;
2171
ebcf1f97
LP
2172 r = c->callback(bus, m, c->userdata, &error_buffer);
2173 r = bus_maybe_reply_error(m, r, &error_buffer);
718db961
LP
2174 free(c);
2175
718db961
LP
2176 goto finish;
2177 }
2178
2179 /* Then, synthesize a Disconnected message */
2180 r = sd_bus_message_new_signal(
2181 bus,
2182 "/org/freedesktop/DBus/Local",
2183 "org.freedesktop.DBus.Local",
2184 "Disconnected",
2185 &m);
2186 if (r < 0)
2187 return r;
2188
34a2c9e8
LP
2189 m->sender = "org.freedesktop.DBus.Local";
2190
7adc46fc 2191 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2192 if (r < 0)
2193 return r;
2194
2195 sd_bus_close(bus);
2196
2197 bus->current = m;
2198 bus->iteration_counter++;
2199
2200 r = process_filter(bus, m);
2201 if (r != 0)
2202 goto finish;
2203
2204 r = process_match(bus, m);
2205 if (r != 0)
2206 goto finish;
2207
2208 if (ret) {
2209 *ret = m;
2210 m = NULL;
2211 }
2212
2213 r = 1;
2214
2215finish:
2216 bus->current = NULL;
2217 return r;
2218}
2219
d9f644e2 2220_public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
8ce2afd6 2221 BUS_DONT_DESTROY(bus);
29ddb38f 2222 int r;
0a72c2bd 2223
992c052c
LP
2224 /* Returns 0 when we didn't do anything. This should cause the
2225 * caller to invoke sd_bus_wait() before returning the next
2226 * time. Returns > 0 when we did something, which possibly
2227 * means *ret is filled in with an unprocessed message. */
0a72c2bd 2228
d6888822
LP
2229 assert_return(bus, -EINVAL);
2230 assert_return(!bus_pid_changed(bus), -ECHILD);
0a72c2bd 2231
992c052c 2232 /* We don't allow recursively invoking sd_bus_process(). */
718db961 2233 assert_return(!bus->current, -EBUSY);
0a72c2bd 2234
992c052c 2235 switch (bus->state) {
0a72c2bd 2236
992c052c
LP
2237 case BUS_UNSET:
2238 case BUS_CLOSED:
2239 return -ENOTCONN;
0a72c2bd 2240
992c052c
LP
2241 case BUS_OPENING:
2242 r = bus_socket_process_opening(bus);
32f46480 2243 if (r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2244 bus_enter_closing(bus);
2245 r = 1;
2246 } else if (r < 0)
29ddb38f 2247 return r;
992c052c
LP
2248 if (ret)
2249 *ret = NULL;
a652755d
LP
2250 return r;
2251
992c052c 2252 case BUS_AUTHENTICATING:
992c052c 2253 r = bus_socket_process_authenticating(bus);
32f46480 2254 if (r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2255 bus_enter_closing(bus);
2256 r = 1;
2257 } else if (r < 0)
29ddb38f 2258 return r;
718db961 2259
992c052c
LP
2260 if (ret)
2261 *ret = NULL;
718db961 2262
992c052c 2263 return r;
a652755d 2264
992c052c
LP
2265 case BUS_RUNNING:
2266 case BUS_HELLO:
992c052c 2267 r = process_running(bus, ret);
32f46480 2268 if (r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2269 bus_enter_closing(bus);
2270 r = 1;
2271
2272 if (ret)
2273 *ret = NULL;
2274 }
43a43f50 2275
43a43f50 2276 return r;
718db961
LP
2277
2278 case BUS_CLOSING:
2279 return process_closing(bus, ret);
992c052c 2280 }
43a43f50 2281
992c052c 2282 assert_not_reached("Unknown state");
e3017af9
LP
2283}
2284
992c052c
LP
2285static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2286 struct pollfd p[2] = {};
2287 int r, e, n;
2288 struct timespec ts;
8efd6381 2289 usec_t m = (usec_t) -1;
adcdb374
LP
2290
2291 assert(bus);
718db961
LP
2292
2293 if (bus->state == BUS_CLOSING)
2294 return 1;
2295
d6888822 2296 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
adcdb374 2297
992c052c
LP
2298 e = sd_bus_get_events(bus);
2299 if (e < 0)
2300 return e;
adcdb374 2301
992c052c 2302 if (need_more)
8efd6381
LP
2303 /* The caller really needs some more data, he doesn't
2304 * care about what's already read, or any timeouts
2305 * except its own.*/
992c052c 2306 e |= POLLIN;
992c052c 2307 else {
8efd6381
LP
2308 usec_t until;
2309 /* The caller wants to process if there's something to
2310 * process, but doesn't care otherwise */
2311
2312 r = sd_bus_get_timeout(bus, &until);
2313 if (r < 0)
2314 return r;
2315 if (r > 0) {
2316 usec_t nw;
2317 nw = now(CLOCK_MONOTONIC);
2318 m = until > nw ? until - nw : 0;
2319 }
992c052c 2320 }
adcdb374 2321
992c052c
LP
2322 if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
2323 m = timeout_usec;
adcdb374 2324
992c052c
LP
2325 p[0].fd = bus->input_fd;
2326 if (bus->output_fd == bus->input_fd) {
2327 p[0].events = e;
2328 n = 1;
2329 } else {
2330 p[0].events = e & POLLIN;
2331 p[1].fd = bus->output_fd;
2332 p[1].events = e & POLLOUT;
2333 n = 2;
adcdb374
LP
2334 }
2335
992c052c 2336 r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
adcdb374 2337 if (r < 0)
992c052c 2338 return -errno;
adcdb374 2339
992c052c 2340 return r > 0 ? 1 : 0;
adcdb374
LP
2341}
2342
d9f644e2 2343_public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
9db76355 2344
d6888822 2345 assert_return(bus, -EINVAL);
d6888822 2346 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2347
718db961
LP
2348 if (bus->state == BUS_CLOSING)
2349 return 0;
2350
2351 assert_return(BUS_IS_OPEN(bus->state) , -ENOTCONN);
2352
992c052c
LP
2353 if (bus->rqueue_size > 0)
2354 return 0;
9db76355 2355
992c052c
LP
2356 return bus_poll(bus, false, timeout_usec);
2357}
9db76355 2358
d9f644e2 2359_public_ int sd_bus_flush(sd_bus *bus) {
992c052c 2360 int r;
9db76355 2361
d6888822 2362 assert_return(bus, -EINVAL);
d6888822 2363 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2364
718db961
LP
2365 if (bus->state == BUS_CLOSING)
2366 return 0;
2367
2368 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
2369
992c052c
LP
2370 r = bus_ensure_running(bus);
2371 if (r < 0)
2372 return r;
9db76355 2373
992c052c
LP
2374 if (bus->wqueue_size <= 0)
2375 return 0;
9db76355 2376
992c052c
LP
2377 for (;;) {
2378 r = dispatch_wqueue(bus);
32f46480
LP
2379 if (r < 0) {
2380 if (r == -EPIPE || r == -ENOTCONN || r == -ESHUTDOWN)
2381 bus_enter_closing(bus);
2382
9db76355 2383 return r;
32f46480 2384 }
9db76355 2385
992c052c
LP
2386 if (bus->wqueue_size <= 0)
2387 return 0;
9db76355 2388
992c052c 2389 r = bus_poll(bus, false, (uint64_t) -1);
9db76355
LP
2390 if (r < 0)
2391 return r;
9db76355 2392 }
9db76355
LP
2393}
2394
d9f644e2
ZJS
2395_public_ int sd_bus_add_filter(sd_bus *bus,
2396 sd_bus_message_handler_t callback,
2397 void *userdata) {
2398
992c052c 2399 struct filter_callback *f;
de1c301e 2400
d6888822
LP
2401 assert_return(bus, -EINVAL);
2402 assert_return(callback, -EINVAL);
2403 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2404
992c052c
LP
2405 f = new0(struct filter_callback, 1);
2406 if (!f)
29ddb38f 2407 return -ENOMEM;
992c052c
LP
2408 f->callback = callback;
2409 f->userdata = userdata;
29ddb38f 2410
992c052c 2411 bus->filter_callbacks_modified = true;
71fda00f 2412 LIST_PREPEND(callbacks, bus->filter_callbacks, f);
de1c301e
LP
2413 return 0;
2414}
a652755d 2415
d9f644e2
ZJS
2416_public_ int sd_bus_remove_filter(sd_bus *bus,
2417 sd_bus_message_handler_t callback,
2418 void *userdata) {
2419
992c052c 2420 struct filter_callback *f;
a652755d 2421
d6888822
LP
2422 assert_return(bus, -EINVAL);
2423 assert_return(callback, -EINVAL);
2424 assert_return(!bus_pid_changed(bus), -ECHILD);
a652755d 2425
992c052c
LP
2426 LIST_FOREACH(callbacks, f, bus->filter_callbacks) {
2427 if (f->callback == callback && f->userdata == userdata) {
2428 bus->filter_callbacks_modified = true;
71fda00f 2429 LIST_REMOVE(callbacks, bus->filter_callbacks, f);
992c052c
LP
2430 free(f);
2431 return 1;
29ddb38f
LP
2432 }
2433 }
2434
992c052c 2435 return 0;
a652755d 2436}
392d5b37 2437
d9f644e2
ZJS
2438_public_ int sd_bus_add_match(sd_bus *bus,
2439 const char *match,
2440 sd_bus_message_handler_t callback,
2441 void *userdata) {
2442
992c052c
LP
2443 struct bus_match_component *components = NULL;
2444 unsigned n_components = 0;
2445 uint64_t cookie = 0;
2446 int r = 0;
392d5b37 2447
d6888822
LP
2448 assert_return(bus, -EINVAL);
2449 assert_return(match, -EINVAL);
2450 assert_return(!bus_pid_changed(bus), -ECHILD);
392d5b37 2451
992c052c
LP
2452 r = bus_match_parse(match, &components, &n_components);
2453 if (r < 0)
2454 goto finish;
29ddb38f 2455
992c052c
LP
2456 if (bus->bus_client) {
2457 cookie = ++bus->match_cookie;
29ddb38f 2458
992c052c
LP
2459 r = bus_add_match_internal(bus, match, components, n_components, cookie);
2460 if (r < 0)
2461 goto finish;
392d5b37
LP
2462 }
2463
992c052c
LP
2464 bus->match_callbacks_modified = true;
2465 r = bus_match_add(&bus->match_callbacks, components, n_components, callback, userdata, cookie, NULL);
29ddb38f 2466 if (r < 0) {
992c052c
LP
2467 if (bus->bus_client)
2468 bus_remove_match_internal(bus, match, cookie);
29ddb38f 2469 }
917b5dc7 2470
992c052c
LP
2471finish:
2472 bus_match_parse_free(components, n_components);
2473 return r;
917b5dc7
LP
2474}
2475
d9f644e2
ZJS
2476_public_ int sd_bus_remove_match(sd_bus *bus,
2477 const char *match,
2478 sd_bus_message_handler_t callback,
2479 void *userdata) {
2480
992c052c
LP
2481 struct bus_match_component *components = NULL;
2482 unsigned n_components = 0;
2483 int r = 0, q = 0;
2484 uint64_t cookie = 0;
917b5dc7 2485
d6888822
LP
2486 assert_return(bus, -EINVAL);
2487 assert_return(match, -EINVAL);
2488 assert_return(!bus_pid_changed(bus), -ECHILD);
917b5dc7 2489
992c052c 2490 r = bus_match_parse(match, &components, &n_components);
29ddb38f
LP
2491 if (r < 0)
2492 return r;
f10dda3b 2493
992c052c
LP
2494 bus->match_callbacks_modified = true;
2495 r = bus_match_remove(&bus->match_callbacks, components, n_components, callback, userdata, &cookie);
f10dda3b 2496
992c052c
LP
2497 if (bus->bus_client)
2498 q = bus_remove_match_internal(bus, match, cookie);
f10dda3b 2499
992c052c 2500 bus_match_parse_free(components, n_components);
f10dda3b 2501
992c052c 2502 return r < 0 ? r : q;
f10dda3b
LP
2503}
2504
992c052c
LP
2505bool bus_pid_changed(sd_bus *bus) {
2506 assert(bus);
f10dda3b 2507
992c052c
LP
2508 /* We don't support people creating a bus connection and
2509 * keeping it around over a fork(). Let's complain. */
d5a2b9a6 2510
992c052c 2511 return bus->original_pid != getpid();
d5a2b9a6 2512}
40ca29a1
LP
2513
2514static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
0927756b 2515 sd_bus *bus = userdata;
40ca29a1
LP
2516 int r;
2517
2518 assert(bus);
2519
2520 r = sd_bus_process(bus, NULL);
2521 if (r < 0)
2522 return r;
2523
2524 return 1;
2525}
2526
2527static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
0927756b 2528 sd_bus *bus = userdata;
40ca29a1
LP
2529 int r;
2530
2531 assert(bus);
2532
2533 r = sd_bus_process(bus, NULL);
2534 if (r < 0)
2535 return r;
2536
2537 return 1;
2538}
2539
2540static int prepare_callback(sd_event_source *s, void *userdata) {
2541 sd_bus *bus = userdata;
2542 int r, e;
2543 usec_t until;
2544
2545 assert(s);
2546 assert(bus);
2547
2548 e = sd_bus_get_events(bus);
2549 if (e < 0)
2550 return e;
2551
2552 if (bus->output_fd != bus->input_fd) {
2553
2554 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
2555 if (r < 0)
2556 return r;
2557
2558 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
2559 if (r < 0)
2560 return r;
2561 } else {
2562 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
2563 if (r < 0)
2564 return r;
2565 }
2566
2567 r = sd_bus_get_timeout(bus, &until);
2568 if (r < 0)
2569 return r;
2570 if (r > 0) {
2571 int j;
2572
2573 j = sd_event_source_set_time(bus->time_event_source, until);
2574 if (j < 0)
2575 return j;
2576 }
2577
2578 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
2579 if (r < 0)
2580 return r;
2581
2582 return 1;
2583}
2584
abc5fe72
LP
2585static int quit_callback(sd_event_source *event, void *userdata) {
2586 sd_bus *bus = userdata;
2587
2588 assert(event);
2589
2590 sd_bus_flush(bus);
2591
2592 return 1;
2593}
2594
d9f644e2 2595_public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
40ca29a1
LP
2596 int r;
2597
2598 assert_return(bus, -EINVAL);
40ca29a1
LP
2599 assert_return(!bus->event, -EBUSY);
2600
2601 assert(!bus->input_io_event_source);
2602 assert(!bus->output_io_event_source);
2603 assert(!bus->time_event_source);
2604
76b54375
LP
2605 if (event)
2606 bus->event = sd_event_ref(event);
2607 else {
2608 r = sd_event_default(&bus->event);
2609 if (r < 0)
2610 return r;
2611 }
40ca29a1 2612
76b54375 2613 r = sd_event_add_io(bus->event, bus->input_fd, 0, io_callback, bus, &bus->input_io_event_source);
40ca29a1
LP
2614 if (r < 0)
2615 goto fail;
2616
2617 r = sd_event_source_set_priority(bus->input_io_event_source, priority);
2618 if (r < 0)
2619 goto fail;
2620
2621 if (bus->output_fd != bus->input_fd) {
76b54375 2622 r = sd_event_add_io(bus->event, bus->output_fd, 0, io_callback, bus, &bus->output_io_event_source);
40ca29a1
LP
2623 if (r < 0)
2624 goto fail;
2625
2626 r = sd_event_source_set_priority(bus->output_io_event_source, priority);
2627 if (r < 0)
2628 goto fail;
2629 }
2630
2631 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
2632 if (r < 0)
2633 goto fail;
2634
76b54375 2635 r = sd_event_add_monotonic(bus->event, 0, 0, time_callback, bus, &bus->time_event_source);
40ca29a1
LP
2636 if (r < 0)
2637 goto fail;
2638
2639 r = sd_event_source_set_priority(bus->time_event_source, priority);
2640 if (r < 0)
2641 goto fail;
2642
76b54375 2643 r = sd_event_add_quit(bus->event, quit_callback, bus, &bus->quit_event_source);
abc5fe72
LP
2644 if (r < 0)
2645 goto fail;
2646
40ca29a1
LP
2647 return 0;
2648
2649fail:
2650 sd_bus_detach_event(bus);
2651 return r;
2652}
2653
d9f644e2 2654_public_ int sd_bus_detach_event(sd_bus *bus) {
40ca29a1 2655 assert_return(bus, -EINVAL);
a82cafb9
LP
2656
2657 if (!bus->event)
2658 return 0;
40ca29a1 2659
86befb40
LP
2660 if (bus->input_io_event_source) {
2661 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
40ca29a1 2662 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
86befb40 2663 }
40ca29a1 2664
86befb40
LP
2665 if (bus->output_io_event_source) {
2666 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
40ca29a1 2667 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
86befb40 2668 }
40ca29a1 2669
86befb40
LP
2670 if (bus->time_event_source) {
2671 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
40ca29a1 2672 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
86befb40 2673 }
40ca29a1 2674
86befb40
LP
2675 if (bus->quit_event_source) {
2676 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
abc5fe72 2677 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
86befb40 2678 }
abc5fe72 2679
40ca29a1
LP
2680 if (bus->event)
2681 bus->event = sd_event_unref(bus->event);
2682
a82cafb9 2683 return 1;
40ca29a1 2684}
affff0b6 2685
2be44176
LP
2686_public_ sd_event* sd_bus_get_event(sd_bus *bus) {
2687 assert_return(bus, NULL);
2688
2689 return bus->event;
2690}
2691
76b54375 2692_public_ sd_bus_message* sd_bus_get_current(sd_bus *bus) {
affff0b6
LP
2693 assert_return(bus, NULL);
2694
2695 return bus->current;
2696}
76b54375
LP
2697
2698static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
2699 sd_bus *b = NULL;
2700 int r;
2701
2702 assert(bus_open);
2703 assert(default_bus);
2704
2705 if (!ret)
2706 return !!*default_bus;
2707
2708 if (*default_bus) {
2709 *ret = sd_bus_ref(*default_bus);
2710 return 0;
2711 }
2712
2713 r = bus_open(&b);
2714 if (r < 0)
2715 return r;
2716
2717 b->default_bus_ptr = default_bus;
2718 b->tid = gettid();
2719 *default_bus = b;
2720
2721 *ret = b;
2722 return 1;
2723}
2724
2725_public_ int sd_bus_default_system(sd_bus **ret) {
2726 static __thread sd_bus *default_system_bus = NULL;
2727
2728 return bus_default(sd_bus_open_system, &default_system_bus, ret);
2729}
2730
2731_public_ int sd_bus_default_user(sd_bus **ret) {
2732 static __thread sd_bus *default_user_bus = NULL;
2733
2734 return bus_default(sd_bus_open_user, &default_user_bus, ret);
2735}
2736
2737_public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
2738 assert_return(b, -EINVAL);
2739 assert_return(tid, -EINVAL);
2740 assert_return(!bus_pid_changed(b), -ECHILD);
2741
2742 if (b->tid != 0) {
2743 *tid = b->tid;
2744 return 0;
2745 }
2746
2747 if (b->event)
2748 return sd_event_get_tid(b->event, tid);
2749
2750 return -ENXIO;
2751}
28383ba1
LP
2752
2753_public_ char *sd_bus_label_escape(const char *s) {
2754 char *r, *t;
2755 const char *f;
2756
2757 assert_return(s, NULL);
2758
2759 /* Escapes all chars that D-Bus' object path cannot deal
2760 * with. Can be reversed with bus_path_unescape(). We special
2761 * case the empty string. */
2762
2763 if (*s == 0)
2764 return strdup("_");
2765
2766 r = new(char, strlen(s)*3 + 1);
2767 if (!r)
2768 return NULL;
2769
2770 for (f = s, t = r; *f; f++) {
2771
2772 /* Escape everything that is not a-zA-Z0-9. We also
2773 * escape 0-9 if it's the first character */
2774
2775 if (!(*f >= 'A' && *f <= 'Z') &&
2776 !(*f >= 'a' && *f <= 'z') &&
2777 !(f > s && *f >= '0' && *f <= '9')) {
2778 *(t++) = '_';
2779 *(t++) = hexchar(*f >> 4);
2780 *(t++) = hexchar(*f);
2781 } else
2782 *(t++) = *f;
2783 }
2784
2785 *t = 0;
2786
2787 return r;
2788}
2789
2790_public_ char *sd_bus_label_unescape(const char *f) {
2791 char *r, *t;
2792
2793 assert_return(f, NULL);
2794
2795 /* Special case for the empty string */
2796 if (streq(f, "_"))
2797 return strdup("");
2798
2799 r = new(char, strlen(f) + 1);
2800 if (!r)
2801 return NULL;
2802
2803 for (t = r; *f; f++) {
2804
2805 if (*f == '_') {
2806 int a, b;
2807
2808 if ((a = unhexchar(f[1])) < 0 ||
2809 (b = unhexchar(f[2])) < 0) {
2810 /* Invalid escape code, let's take it literal then */
2811 *(t++) = '_';
2812 } else {
2813 *(t++) = (char) ((a << 4) | b);
2814 f += 2;
2815 }
2816 } else
2817 *(t++) = *f;
2818 }
2819
2820 *t = 0;
2821
2822 return r;
2823}
5b12334d
LP
2824
2825_public_ int sd_bus_get_peer_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
2826 sd_bus_creds *c;
2827 pid_t pid = 0;
2828 int r;
2829
2830 assert_return(bus, -EINVAL);
95c4fe82 2831 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
5b12334d
LP
2832 assert_return(ret, -EINVAL);
2833 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
2834 assert_return(!bus_pid_changed(bus), -ECHILD);
2835 assert_return(!bus->is_kernel, -ENOTSUP);
2836
2837 if (!bus->ucred_valid && !isempty(bus->label))
2838 return -ENODATA;
2839
2840 c = bus_creds_new();
2841 if (!c)
2842 return -ENOMEM;
2843
2844 if (bus->ucred_valid) {
2845 pid = c->pid = bus->ucred.pid;
2846 c->uid = bus->ucred.uid;
2847 c->gid = bus->ucred.gid;
2848
3310dfd5 2849 c->mask |= (SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID) & mask;
5b12334d
LP
2850 }
2851
2852 if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
2853 c->label = strdup(bus->label);
2854 if (!c->label) {
2855 sd_bus_creds_unref(c);
2856 return -ENOMEM;
2857 }
2858
3310dfd5 2859 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
5b12334d
LP
2860 }
2861
2862 r = bus_creds_add_more(c, mask, pid, 0);
2863 if (r < 0)
2864 return r;
2865
2866 *ret = c;
2867 return 0;
2868}