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