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