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