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