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