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