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