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