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