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