chiark / gitweb /
bus: allow specifying NULL as type string when we want to construct messages with...
[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
1891         u = c->userdata;
1892         if (c->find) {
1893                 r = c->find(bus, path, c->interface, &u, u);
1894                 if (r <= 0)
1895                         return r;
1896         }
1897
1898         if (userdata)
1899                 *userdata = u;
1900
1901         return 1;
1902 }
1903
1904 static void *vtable_property_convert_userdata(const sd_bus_vtable *p, void *u) {
1905         assert(p);
1906
1907         return (uint8_t*) u + p->property.offset;
1908 }
1909
1910 static int vtable_property_get_userdata(
1911                 sd_bus *bus,
1912                 const char *path,
1913                 struct vtable_member *p,
1914                 void **userdata) {
1915
1916         void *u;
1917         int r;
1918
1919         assert(bus);
1920         assert(path);
1921         assert(p);
1922         assert(userdata);
1923
1924         r = node_vtable_get_userdata(bus, path, p->parent, &u);
1925         if (r <= 0)
1926                 return r;
1927
1928         *userdata = vtable_property_convert_userdata(p->vtable, u);
1929         return 1;
1930 }
1931
1932 static int add_enumerated_to_set(sd_bus *bus, const char *prefix, struct node_enumerator *first, Set *s) {
1933         struct node_enumerator *c;
1934         int r;
1935
1936         assert(bus);
1937         assert(prefix);
1938         assert(s);
1939
1940         LIST_FOREACH(enumerators, c, first) {
1941                 char **children = NULL, **k;
1942
1943                 r = c->callback(bus, prefix, &children, c->userdata);
1944                 if (r < 0)
1945                         return r;
1946
1947                 STRV_FOREACH(k, children) {
1948                         if (r < 0) {
1949                                 free(*k);
1950                                 continue;
1951                         }
1952
1953                         if (!object_path_is_valid(*k) && object_path_startswith(*k, prefix)) {
1954                                 free(*k);
1955                                 r = -EINVAL;
1956                                 continue;
1957                         }
1958
1959                         r = set_consume(s, *k);
1960                 }
1961
1962                 free(children);
1963                 if (r < 0)
1964                         return r;
1965         }
1966
1967         return 0;
1968 }
1969
1970 static int add_subtree_to_set(sd_bus *bus, const char *prefix, struct node *n, Set *s) {
1971         struct node *i;
1972         int r;
1973
1974         assert(bus);
1975         assert(prefix);
1976         assert(n);
1977         assert(s);
1978
1979         r = add_enumerated_to_set(bus, prefix, n->enumerators, s);
1980         if (r < 0)
1981                 return r;
1982
1983         LIST_FOREACH(siblings, i, n->child) {
1984                 char *t;
1985
1986                 t = strdup(i->path);
1987                 if (!t)
1988                         return -ENOMEM;
1989
1990                 r = set_consume(s, t);
1991                 if (r < 0 && r != -EEXIST)
1992                         return r;
1993
1994                 r = add_subtree_to_set(bus, prefix, i, s);
1995                 if (r < 0)
1996                         return r;
1997         }
1998
1999         return 0;
2000 }
2001
2002 static int get_child_nodes(sd_bus *bus, const char *prefix, struct node *n, Set **_s) {
2003         Set *s = NULL;
2004         int r;
2005
2006         assert(bus);
2007         assert(n);
2008         assert(_s);
2009
2010         s = set_new(string_hash_func, string_compare_func);
2011         if (!s)
2012                 return -ENOMEM;
2013
2014         r = add_subtree_to_set(bus, prefix, n, s);
2015         if (r < 0) {
2016                 set_free_free(s);
2017                 return r;
2018         }
2019
2020         *_s = s;
2021         return 0;
2022 }
2023
2024 static int node_callbacks_run(
2025                 sd_bus *bus,
2026                 sd_bus_message *m,
2027                 struct node_callback *first,
2028                 bool require_fallback,
2029                 bool *found_object) {
2030
2031         struct node_callback *c;
2032         int r;
2033
2034         assert(bus);
2035         assert(m);
2036         assert(found_object);
2037
2038         LIST_FOREACH(callbacks, c, first) {
2039                 if (require_fallback && !c->is_fallback)
2040                         continue;
2041
2042                 *found_object = true;
2043
2044                 if (c->last_iteration == bus->iteration_counter)
2045                         continue;
2046
2047                 r = sd_bus_message_rewind(m, true);
2048                 if (r < 0)
2049                         return r;
2050
2051                 r = c->callback(bus, m, c->userdata);
2052                 if (r != 0)
2053                         return r;
2054         }
2055
2056         return 0;
2057 }
2058
2059 static int method_callbacks_run(
2060                 sd_bus *bus,
2061                 sd_bus_message *m,
2062                 struct vtable_member *c,
2063                 bool require_fallback,
2064                 bool *found_object) {
2065
2066         const char *signature;
2067         void *u;
2068         int r;
2069
2070         assert(bus);
2071         assert(m);
2072         assert(c);
2073         assert(found_object);
2074
2075         if (require_fallback && !c->parent->is_fallback)
2076                 return 0;
2077
2078         r = node_vtable_get_userdata(bus, m->path, c->parent, &u);
2079         if (r <= 0)
2080                 return r;
2081
2082         *found_object = true;
2083
2084         r = sd_bus_message_rewind(m, true);
2085         if (r < 0)
2086                 return r;
2087
2088         r = sd_bus_message_get_signature(m, true, &signature);
2089         if (r < 0)
2090                 return r;
2091
2092         if (!streq(c->vtable->method.signature, signature)) {
2093                 r = sd_bus_reply_method_errorf(bus, m,
2094                                                "org.freedesktop.DBus.Error.InvalidArgs",
2095                                                "Invalid arguments '%s' to call %s:%s, expecting '%s'.",
2096                                                signature, c->interface, c->member, c->vtable->method.signature);
2097                 if (r < 0)
2098                         return r;
2099
2100                 return 1;
2101         }
2102
2103         return c->vtable->method.handler(bus, m, u);
2104 }
2105
2106 static int property_get_set_callbacks_run(
2107                 sd_bus *bus,
2108                 sd_bus_message *m,
2109                 struct vtable_member *c,
2110                 bool require_fallback,
2111                 bool is_get,
2112                 bool *found_object) {
2113
2114         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2115         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2116         void *u;
2117         int r;
2118
2119         assert(bus);
2120         assert(m);
2121         assert(found_object);
2122
2123         if (require_fallback && !c->parent->is_fallback)
2124                 return 0;
2125
2126         r = vtable_property_get_userdata(bus, m->path, c, &u);
2127         if (r <= 0)
2128                 return r;
2129
2130         *found_object = true;
2131
2132         r = sd_bus_message_new_method_return(bus, m, &reply);
2133         if (r < 0)
2134                 return r;
2135
2136         c->last_iteration = bus->iteration_counter;
2137
2138         if (is_get) {
2139                 r = sd_bus_message_open_container(reply, 'v', c->vtable->property.signature);
2140                 if (r < 0)
2141                         return r;
2142
2143                 if (c->vtable->property.get) {
2144                         r = c->vtable->property.get(bus, m->path, c->interface, c->member, reply, &error, u);
2145                         if (r < 0)
2146                                 return r;
2147                 } else
2148                         assert_not_reached("automatic properties not supported yet");
2149
2150                 if (sd_bus_error_is_set(&error)) {
2151                         r = sd_bus_reply_method_error(bus, m, &error);
2152                         if (r < 0)
2153                                 return r;
2154
2155                         return 1;
2156                 }
2157
2158                 r = sd_bus_message_close_container(reply);
2159                 if (r < 0)
2160                         return r;
2161
2162         } else {
2163                 if (c->vtable->type != _SD_BUS_VTABLE_WRITABLE_PROPERTY)
2164                         sd_bus_error_setf(&error, "org.freedesktop.DBus.Error.PropertyReadOnly", "Property '%s' is not writable.", c->member);
2165                 else  {
2166                         r = sd_bus_message_enter_container(m, 'v', c->vtable->property.signature);
2167                         if (r < 0)
2168                                 return r;
2169
2170                         if (c->vtable->property.set) {
2171                                 r = c->vtable->property.set(bus, m->path, c->interface, c->member, m, &error, u);
2172                                 if (r < 0)
2173                                         return r;
2174                         } else
2175                                 assert_not_reached("automatic properties not supported yet");
2176                 }
2177
2178                 if (sd_bus_error_is_set(&error)) {
2179                         r = sd_bus_reply_method_error(bus, m, &error);
2180                         if (r < 0)
2181                                 return r;
2182
2183                         return 1;
2184                 }
2185
2186                 r = sd_bus_message_exit_container(m);
2187                 if (r < 0)
2188                         return r;
2189         }
2190
2191         r = sd_bus_send(bus, reply, NULL);
2192         if (r < 0)
2193                 return r;
2194
2195         return 1;
2196 }
2197
2198 static int vtable_append_all_properties(
2199                 sd_bus *bus,
2200                 sd_bus_message *reply,
2201                 const char *path,
2202                 struct node_vtable *c,
2203                 void *userdata,
2204                 sd_bus_error *error) {
2205
2206         const sd_bus_vtable *v;
2207         int r;
2208
2209         assert(bus);
2210         assert(reply);
2211         assert(c);
2212
2213         for (v = c->vtable+1; v->type != _SD_BUS_VTABLE_END; v++) {
2214                 if (v->type != _SD_BUS_VTABLE_PROPERTY && v->type != _SD_BUS_VTABLE_WRITABLE_PROPERTY)
2215                         continue;
2216
2217                 r = sd_bus_message_open_container(reply, 'e', "sv");
2218                 if (r < 0)
2219                         return r;
2220
2221                 r = sd_bus_message_append(reply, "s", c->interface);
2222                 if (r < 0)
2223                         return r;
2224
2225                 r = sd_bus_message_open_container(reply, 'v', v->property.signature);
2226                 if (r < 0)
2227                         return r;
2228
2229                 r = v->property.get(bus, path, c->interface, v->property.member, reply, error, vtable_property_convert_userdata(v, userdata));
2230                 if (r < 0)
2231                         return r;
2232
2233                 if (sd_bus_error_is_set(error))
2234                         return 0;
2235
2236                 r = sd_bus_message_close_container(reply);
2237                 if (r < 0)
2238                         return r;
2239
2240                 r = sd_bus_message_close_container(reply);
2241                 if (r < 0)
2242                         return r;
2243         }
2244
2245         return 1;
2246 }
2247
2248 static int property_get_all_callbacks_run(
2249                 sd_bus *bus,
2250                 sd_bus_message *m,
2251                 struct node_vtable *first,
2252                 bool require_fallback,
2253                 const char *iface,
2254                 bool *found_object) {
2255
2256         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2257         struct node_vtable *c;
2258         bool found_interface = false;
2259         int r;
2260
2261         assert(bus);
2262         assert(m);
2263         assert(found_object);
2264
2265         r = sd_bus_message_new_method_return(bus, m, &reply);
2266         if (r < 0)
2267                 return r;
2268
2269         r = sd_bus_message_open_container(reply, 'a', "{sv}");
2270         if (r < 0)
2271                 return r;
2272
2273         LIST_FOREACH(vtables, c, first) {
2274                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2275                 void *u;
2276
2277                 if (require_fallback && !c->is_fallback)
2278                         continue;
2279
2280                 r = node_vtable_get_userdata(bus, m->path, c, &u);
2281                 if (r < 0)
2282                         return r;
2283                 if (r == 0)
2284                         continue;
2285
2286                 *found_object = true;
2287
2288                 if (iface && !streq(c->interface, iface))
2289                         continue;
2290                 found_interface = true;
2291
2292                 c->last_iteration = bus->iteration_counter;
2293
2294                 r = vtable_append_all_properties(bus, reply, m->path, c, u, &error);
2295                 if (r < 0)
2296                         return r;
2297
2298                 if (sd_bus_error_is_set(&error)) {
2299                         r = sd_bus_reply_method_error(bus, m, &error);
2300                         if (r < 0)
2301                                 return r;
2302
2303                         return 1;
2304                 }
2305         }
2306
2307         if (!found_interface) {
2308                 r = sd_bus_reply_method_errorf(
2309                                 bus, m,
2310                                 "org.freedesktop.DBus.Error.UnknownInterface",
2311                                 "Unknown interface '%s'.", iface);
2312                 if (r < 0)
2313                         return r;
2314
2315                 return 1;
2316         }
2317
2318         r = sd_bus_message_close_container(reply);
2319         if (r < 0)
2320                 return r;
2321
2322         r = sd_bus_send(bus, reply, NULL);
2323         if (r < 0)
2324                 return r;
2325
2326         return 1;
2327 }
2328
2329 static bool bus_node_with_object_manager(sd_bus *bus, struct node *n) {
2330         assert(bus);
2331
2332         if (n->object_manager)
2333                 return true;
2334
2335         if (n->parent)
2336                 return bus_node_with_object_manager(bus, n->parent);
2337
2338         return false;
2339 }
2340
2341 static bool bus_node_exists(sd_bus *bus, struct node *n, const char *path, bool require_fallback) {
2342         struct node_vtable *c;
2343         struct node_callback *k;
2344
2345         assert(bus);
2346         assert(n);
2347
2348         /* Tests if there's anything attached directly to this node
2349          * for the specified path */
2350
2351         LIST_FOREACH(callbacks, k, n->callbacks) {
2352                 if (require_fallback && !k->is_fallback)
2353                         continue;
2354
2355                 return true;
2356         }
2357
2358         LIST_FOREACH(vtables, c, n->vtables) {
2359
2360                 if (require_fallback && !c->is_fallback)
2361                         continue;
2362
2363                 if (node_vtable_get_userdata(bus, path, c, NULL) > 0)
2364                         return true;
2365         }
2366
2367         return !require_fallback && (n->enumerators || n->object_manager);
2368 }
2369
2370 static int process_introspect(
2371                 sd_bus *bus,
2372                 sd_bus_message *m,
2373                 struct node *n,
2374                 bool require_fallback,
2375                 bool *found_object) {
2376
2377         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2378         _cleanup_set_free_free_ Set *s = NULL;
2379         struct introspect intro;
2380         struct node_vtable *c;
2381         bool empty;
2382         int r;
2383
2384         assert(bus);
2385         assert(m);
2386         assert(n);
2387         assert(found_object);
2388
2389         r = get_child_nodes(bus, m->path, n, &s);
2390         if (r < 0)
2391                 return r;
2392
2393         r = introspect_begin(&intro);
2394         if (r < 0)
2395                 return r;
2396
2397         r = introspect_write_default_interfaces(&intro, bus_node_with_object_manager(bus, n));
2398         if (r < 0)
2399                 return r;
2400
2401         empty = set_isempty(s);
2402
2403         LIST_FOREACH(vtables, c, n->vtables) {
2404                 if (require_fallback && !c->is_fallback)
2405                         continue;
2406
2407                 r = node_vtable_get_userdata(bus, m->path, c, NULL);
2408                 if (r < 0)
2409                         return r;
2410                 if (r == 0)
2411                         continue;
2412
2413                 empty = false;
2414
2415                 r = introspect_write_interface(&intro, c->interface, c->vtable);
2416                 if (r < 0)
2417                         goto finish;
2418         }
2419
2420         if (empty) {
2421                 /* Nothing?, let's see if we exist at all, and if not
2422                  * refuse to do anything */
2423                 r = bus_node_exists(bus, n, m->path, require_fallback);
2424                 if (r < 0)
2425                         return r;
2426
2427                 if (r == 0)
2428                         goto finish;
2429         }
2430
2431         *found_object = true;
2432
2433         r = introspect_write_child_nodes(&intro, s, m->path);
2434         if (r < 0)
2435                 goto finish;
2436
2437         r = introspect_finish(&intro, bus, m, &reply);
2438         if (r < 0)
2439                 goto finish;
2440
2441         r = sd_bus_send(bus, reply, NULL);
2442         if (r < 0)
2443                 goto finish;
2444
2445         r = 1;
2446
2447 finish:
2448         introspect_free(&intro);
2449         return r;
2450 }
2451
2452 static int object_manager_serialize_vtable(
2453                 sd_bus *bus,
2454                 sd_bus_message *reply,
2455                 const char *path,
2456                 struct node_vtable *c,
2457                 sd_bus_error *error) {
2458
2459         void *u;
2460         int r;
2461
2462         assert(bus);
2463         assert(reply);
2464         assert(path);
2465         assert(c);
2466         assert(error);
2467
2468         r = node_vtable_get_userdata(bus, path, c, &u);
2469         if (r <= 0)
2470                 return r;
2471
2472         r = sd_bus_message_open_container(reply, 'e', "sa{sv}");
2473         if (r < 0)
2474                 return r;
2475
2476         r = sd_bus_message_append(reply, "s", c->interface);
2477         if (r < 0)
2478                 return r;
2479
2480         r = sd_bus_message_open_container(reply, 'a', "{sv}");
2481         if (r < 0)
2482                 return r;
2483
2484         r = vtable_append_all_properties(bus, reply, path, c, u, error);
2485         if (r < 0)
2486                 return r;
2487
2488         r = sd_bus_message_close_container(reply);
2489         if (r < 0)
2490                 return r;
2491
2492         r = sd_bus_message_close_container(reply);
2493         if (r < 0)
2494                 return r;
2495
2496         return 0;
2497 }
2498
2499 static int object_manager_serialize_path(
2500                 sd_bus *bus,
2501                 sd_bus_message *reply,
2502                 const char *prefix,
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(prefix);
2514         assert(path);
2515         assert(error);
2516
2517         n = hashmap_get(bus->nodes, prefix);
2518         if (!n)
2519                 return 0;
2520
2521         r = sd_bus_message_open_container(reply, 'e', "oa{sa{sv}}");
2522         if (r < 0)
2523                 return r;
2524
2525         r = sd_bus_message_append(reply, "o", path);
2526         if (r < 0)
2527                 return r;
2528
2529         r = sd_bus_message_open_container(reply, 'a', "{sa{sv}}");
2530         if (r < 0)
2531                 return r;
2532
2533         LIST_FOREACH(vtables, i, n->vtables) {
2534
2535                 if (require_fallback && !i->is_fallback)
2536                         continue;
2537
2538                 r = object_manager_serialize_vtable(bus, reply, path, i, error);
2539                 if (r < 0)
2540                         return r;
2541                 if (sd_bus_error_is_set(error))
2542                         return 0;
2543         }
2544
2545         r = sd_bus_message_close_container(reply);
2546         if (r < 0)
2547                 return r;
2548
2549         r = sd_bus_message_close_container(reply);
2550         if (r < 0)
2551                 return r;
2552
2553         return 1;
2554 }
2555
2556 static int object_manager_serialize_path_and_fallbacks(
2557                 sd_bus *bus,
2558                 sd_bus_message *reply,
2559                 const char *path,
2560                 sd_bus_error *error) {
2561
2562         size_t pl;
2563         int r;
2564
2565         assert(bus);
2566         assert(reply);
2567         assert(path);
2568         assert(error);
2569
2570         /* First, add all vtables registered for this path */
2571         r = object_manager_serialize_path(bus, reply, path, path, false, error);
2572         if (r < 0)
2573                 return r;
2574         if (sd_bus_error_is_set(error))
2575                 return 0;
2576
2577         /* Second, add fallback vtables registered for any of the prefixes */
2578         pl = strlen(path);
2579         if (pl > 1) {
2580                 char p[pl + 1];
2581                 strcpy(p, path);
2582
2583                 for (;;) {
2584                         char *e;
2585
2586                         e = strrchr(p, '/');
2587                         if (e == p || !e)
2588                                 break;
2589
2590                         *e = 0;
2591
2592                         r = object_manager_serialize_path(bus, reply, p, path, true, error);
2593                         if (r < 0)
2594                                 return r;
2595
2596                         if (sd_bus_error_is_set(error))
2597                                 return 0;
2598                 }
2599         }
2600
2601         return 0;
2602 }
2603
2604 static int process_get_managed_objects(
2605                 sd_bus *bus,
2606                 sd_bus_message *m,
2607                 struct node *n,
2608                 bool require_fallback,
2609                 bool *found_object) {
2610
2611         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2612         _cleanup_set_free_free_ Set *s = NULL;
2613         bool empty;
2614         int r;
2615
2616         assert(bus);
2617         assert(m);
2618         assert(n);
2619         assert(found_object);
2620
2621         if (!bus_node_with_object_manager(bus, n))
2622                 return 0;
2623
2624         r = get_child_nodes(bus, m->path, n, &s);
2625         if (r < 0)
2626                 return r;
2627
2628         r = sd_bus_message_new_method_return(bus, m, &reply);
2629         if (r < 0)
2630                 return r;
2631
2632         r = sd_bus_message_open_container(reply, 'a', "{oa{sa{sv}}}");
2633         if (r < 0)
2634                 return r;
2635
2636         empty = set_isempty(s);
2637         if (empty) {
2638                 struct node_vtable *c;
2639
2640                 /* Hmm, so we have no children? Then let's check
2641                  * whether we exist at all, i.e. whether at least one
2642                  * vtable exists. */
2643
2644                 LIST_FOREACH(vtables, c, n->vtables) {
2645
2646                         if (require_fallback && !c->is_fallback)
2647                                 continue;
2648
2649                         if (r < 0)
2650                                 return r;
2651                         if (r == 0)
2652                                 continue;
2653
2654                         empty = false;
2655                         break;
2656                 }
2657
2658                 if (empty)
2659                         return 0;
2660         } else {
2661                 Iterator i;
2662                 char *path;
2663
2664                 SET_FOREACH(path, s, i) {
2665                         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2666
2667                         r = object_manager_serialize_path_and_fallbacks(bus, reply, path, &error);
2668                         if (r < 0)
2669                                 return -ENOMEM;
2670
2671                         if (sd_bus_error_is_set(&error)) {
2672                                 r = sd_bus_reply_method_error(bus, m, &error);
2673                                 if (r < 0)
2674                                         return r;
2675
2676                                 return 1;
2677                         }
2678                 }
2679         }
2680
2681         r = sd_bus_message_close_container(reply);
2682         if (r < 0)
2683                 return r;
2684
2685         r = sd_bus_send(bus, reply, NULL);
2686         if (r < 0)
2687                 return r;
2688
2689         return 1;
2690 }
2691
2692 static int object_find_and_run(
2693                 sd_bus *bus,
2694                 sd_bus_message *m,
2695                 const char *p,
2696                 bool require_fallback,
2697                 bool *found_object) {
2698
2699         struct node *n;
2700         struct vtable_member vtable_key, *v;
2701         int r;
2702
2703         assert(bus);
2704         assert(m);
2705         assert(p);
2706         assert(found_object);
2707
2708         n = hashmap_get(bus->nodes, p);
2709         if (!n)
2710                 return 0;
2711
2712         /* First, try object callbacks */
2713         r = node_callbacks_run(bus, m, n->callbacks, require_fallback, found_object);
2714         if (r != 0)
2715                 return r;
2716
2717         if (!m->interface || !m->member)
2718                 return 0;
2719
2720         /* Then, look for a known method */
2721         vtable_key.path = (char*) p;
2722         vtable_key.interface = m->interface;
2723         vtable_key.member = m->member;
2724
2725         v = hashmap_get(bus->vtable_methods, &vtable_key);
2726         if (v) {
2727                 r = method_callbacks_run(bus, m, v, require_fallback, found_object);
2728                 if (r != 0)
2729                         return r;
2730         }
2731
2732         /* Then, look for a known property */
2733         if (streq(m->interface, "org.freedesktop.DBus.Properties")) {
2734                 bool get = false;
2735
2736                 get = streq(m->member, "Get");
2737
2738                 if (get || streq(m->member, "Set")) {
2739
2740                         r = sd_bus_message_rewind(m, true);
2741                         if (r < 0)
2742                                 return r;
2743
2744                         vtable_key.path = (char*) p;
2745
2746                         r = sd_bus_message_read(m, "ss", &vtable_key.interface, &vtable_key.member);
2747                         if (r < 0)
2748                                 return r;
2749
2750                         v = hashmap_get(bus->vtable_properties, &vtable_key);
2751                         if (v) {
2752                                 r = property_get_set_callbacks_run(bus, m, v, require_fallback, get, found_object);
2753                                 if (r != 0)
2754                                         return r;
2755                         }
2756
2757                 } else if (streq(m->member, "GetAll")) {
2758                         const char *iface;
2759
2760                         r = sd_bus_message_rewind(m, true);
2761                         if (r < 0)
2762                                 return r;
2763
2764                         r = sd_bus_message_read(m, "s", &iface);
2765                         if (r < 0)
2766                                 return r;
2767
2768                         if (iface[0] == 0)
2769                                 iface = NULL;
2770
2771                         r = property_get_all_callbacks_run(bus, m, n->vtables, require_fallback, iface, found_object);
2772                         if (r != 0)
2773                                 return r;
2774                 }
2775
2776         } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
2777
2778                 r = process_introspect(bus, m, n, require_fallback, found_object);
2779                 if (r != 0)
2780                         return r;
2781
2782         } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus.ObjectManager", "GetManagedObjects")) {
2783
2784                 r = process_get_managed_objects(bus, m, n, require_fallback, found_object);
2785                 if (r != 0)
2786                         return r;
2787         }
2788
2789         if (!*found_object) {
2790                 r = bus_node_exists(bus, n, m->path, require_fallback);
2791                 if (r < 0)
2792                         return r;
2793
2794                 if (r > 0)
2795                         *found_object = true;
2796         }
2797
2798         return 0;
2799 }
2800
2801 static int process_object(sd_bus *bus, sd_bus_message *m) {
2802         int r;
2803         size_t pl;
2804         bool found_object = false;
2805
2806         assert(bus);
2807         assert(m);
2808
2809         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
2810                 return 0;
2811
2812         if (!m->path)
2813                 return 0;
2814
2815         if (hashmap_isempty(bus->nodes))
2816                 return 0;
2817
2818         pl = strlen(m->path);
2819         do {
2820                 char p[pl+1];
2821
2822                 bus->nodes_modified = false;
2823
2824                 r = object_find_and_run(bus, m, m->path, false, &found_object);
2825                 if (r != 0)
2826                         return r;
2827
2828                 /* Look for fallback prefixes */
2829                 strcpy(p, m->path);
2830                 for (;;) {
2831                         char *e;
2832
2833                         if (streq(p, "/"))
2834                                 break;
2835
2836                         if (bus->nodes_modified)
2837                                 break;
2838
2839                         e = strrchr(p, '/');
2840                         assert(e);
2841                         if (e == p)
2842                                 *(e+1) = 0;
2843                         else
2844                                 *e = 0;
2845
2846                         r = object_find_and_run(bus, m, p, true, &found_object);
2847                         if (r != 0)
2848                                 return r;
2849                 }
2850
2851         } while (bus->nodes_modified);
2852
2853         if (!found_object)
2854                 return 0;
2855
2856         if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Get") ||
2857             sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Set"))
2858                 r = sd_bus_reply_method_errorf(
2859                                 bus, m,
2860                                 "org.freedesktop.DBus.Error.UnknownProperty",
2861                                 "Unknown property or interface.");
2862         else
2863                 r = sd_bus_reply_method_errorf(
2864                                 bus, m,
2865                                 "org.freedesktop.DBus.Error.UnknownMethod",
2866                                 "Unknown method '%s' or interface '%s'.", m->member, m->interface);
2867
2868         if (r < 0)
2869                 return r;
2870
2871         return 1;
2872 }
2873
2874 static int process_message(sd_bus *bus, sd_bus_message *m) {
2875         int r;
2876
2877         assert(bus);
2878         assert(m);
2879
2880         bus->iteration_counter++;
2881
2882         r = process_hello(bus, m);
2883         if (r != 0)
2884                 return r;
2885
2886         r = process_reply(bus, m);
2887         if (r != 0)
2888                 return r;
2889
2890         r = process_filter(bus, m);
2891         if (r != 0)
2892                 return r;
2893
2894         r = process_match(bus, m);
2895         if (r != 0)
2896                 return r;
2897
2898         r = process_builtin(bus, m);
2899         if (r != 0)
2900                 return r;
2901
2902         return process_object(bus, m);
2903 }
2904
2905 static int process_running(sd_bus *bus, sd_bus_message **ret) {
2906         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2907         int r;
2908
2909         assert(bus);
2910         assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
2911
2912         r = process_timeout(bus);
2913         if (r != 0)
2914                 goto null_message;
2915
2916         r = dispatch_wqueue(bus);
2917         if (r != 0)
2918                 goto null_message;
2919
2920         r = dispatch_rqueue(bus, &m);
2921         if (r < 0)
2922                 return r;
2923         if (!m)
2924                 goto null_message;
2925
2926         r = process_message(bus, m);
2927         if (r != 0)
2928                 goto null_message;
2929
2930         if (ret) {
2931                 r = sd_bus_message_rewind(m, true);
2932                 if (r < 0)
2933                         return r;
2934
2935                 *ret = m;
2936                 m = NULL;
2937                 return 1;
2938         }
2939
2940         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL) {
2941
2942                 r = sd_bus_reply_method_errorf(
2943                                 bus, m,
2944                                 "org.freedesktop.DBus.Error.UnknownObject",
2945                                 "Unknown object '%s'.", m->path);
2946                 if (r < 0)
2947                         return r;
2948         }
2949
2950         return 1;
2951
2952 null_message:
2953         if (r >= 0 && ret)
2954                 *ret = NULL;
2955
2956         return r;
2957 }
2958
2959 int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
2960         int r;
2961
2962         /* Returns 0 when we didn't do anything. This should cause the
2963          * caller to invoke sd_bus_wait() before returning the next
2964          * time. Returns > 0 when we did something, which possibly
2965          * means *ret is filled in with an unprocessed message. */
2966
2967         if (!bus)
2968                 return -EINVAL;
2969         if (bus_pid_changed(bus))
2970                 return -ECHILD;
2971
2972         /* We don't allow recursively invoking sd_bus_process(). */
2973         if (bus->processing)
2974                 return -EBUSY;
2975
2976         switch (bus->state) {
2977
2978         case BUS_UNSET:
2979         case BUS_CLOSED:
2980                 return -ENOTCONN;
2981
2982         case BUS_OPENING:
2983                 r = bus_socket_process_opening(bus);
2984                 if (r < 0)
2985                         return r;
2986                 if (ret)
2987                         *ret = NULL;
2988                 return r;
2989
2990         case BUS_AUTHENTICATING:
2991
2992                 r = bus_socket_process_authenticating(bus);
2993                 if (r < 0)
2994                         return r;
2995                 if (ret)
2996                         *ret = NULL;
2997                 return r;
2998
2999         case BUS_RUNNING:
3000         case BUS_HELLO:
3001
3002                 bus->processing = true;
3003                 r = process_running(bus, ret);
3004                 bus->processing = false;
3005
3006                 return r;
3007         }
3008
3009         assert_not_reached("Unknown state");
3010 }
3011
3012 static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
3013         struct pollfd p[2] = {};
3014         int r, e, n;
3015         struct timespec ts;
3016         usec_t until, m;
3017
3018         assert(bus);
3019
3020         if (!BUS_IS_OPEN(bus->state))
3021                 return -ENOTCONN;
3022
3023         e = sd_bus_get_events(bus);
3024         if (e < 0)
3025                 return e;
3026
3027         if (need_more)
3028                 e |= POLLIN;
3029
3030         r = sd_bus_get_timeout(bus, &until);
3031         if (r < 0)
3032                 return r;
3033         if (r == 0)
3034                 m = (uint64_t) -1;
3035         else {
3036                 usec_t nw;
3037                 nw = now(CLOCK_MONOTONIC);
3038                 m = until > nw ? until - nw : 0;
3039         }
3040
3041         if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
3042                 m = timeout_usec;
3043
3044         p[0].fd = bus->input_fd;
3045         if (bus->output_fd == bus->input_fd) {
3046                 p[0].events = e;
3047                 n = 1;
3048         } else {
3049                 p[0].events = e & POLLIN;
3050                 p[1].fd = bus->output_fd;
3051                 p[1].events = e & POLLOUT;
3052                 n = 2;
3053         }
3054
3055         r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
3056         if (r < 0)
3057                 return -errno;
3058
3059         return r > 0 ? 1 : 0;
3060 }
3061
3062 int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
3063
3064         if (!bus)
3065                 return -EINVAL;
3066         if (!BUS_IS_OPEN(bus->state))
3067                 return -ENOTCONN;
3068         if (bus_pid_changed(bus))
3069                 return -ECHILD;
3070
3071         if (bus->rqueue_size > 0)
3072                 return 0;
3073
3074         return bus_poll(bus, false, timeout_usec);
3075 }
3076
3077 int sd_bus_flush(sd_bus *bus) {
3078         int r;
3079
3080         if (!bus)
3081                 return -EINVAL;
3082         if (!BUS_IS_OPEN(bus->state))
3083                 return -ENOTCONN;
3084         if (bus_pid_changed(bus))
3085                 return -ECHILD;
3086
3087         r = bus_ensure_running(bus);
3088         if (r < 0)
3089                 return r;
3090
3091         if (bus->wqueue_size <= 0)
3092                 return 0;
3093
3094         for (;;) {
3095                 r = dispatch_wqueue(bus);
3096                 if (r < 0)
3097                         return r;
3098
3099                 if (bus->wqueue_size <= 0)
3100                         return 0;
3101
3102                 r = bus_poll(bus, false, (uint64_t) -1);
3103                 if (r < 0)
3104                         return r;
3105         }
3106 }
3107
3108 int sd_bus_add_filter(sd_bus *bus, sd_bus_message_handler_t callback, void *userdata) {
3109         struct filter_callback *f;
3110
3111         if (!bus)
3112                 return -EINVAL;
3113         if (!callback)
3114                 return -EINVAL;
3115         if (bus_pid_changed(bus))
3116                 return -ECHILD;
3117
3118         f = new0(struct filter_callback, 1);
3119         if (!f)
3120                 return -ENOMEM;
3121         f->callback = callback;
3122         f->userdata = userdata;
3123
3124         bus->filter_callbacks_modified = true;
3125         LIST_PREPEND(struct filter_callback, callbacks, bus->filter_callbacks, f);
3126         return 0;
3127 }
3128
3129 int sd_bus_remove_filter(sd_bus *bus, sd_bus_message_handler_t callback, void *userdata) {
3130         struct filter_callback *f;
3131
3132         if (!bus)
3133                 return -EINVAL;
3134         if (!callback)
3135                 return -EINVAL;
3136         if (bus_pid_changed(bus))
3137                 return -ECHILD;
3138
3139         LIST_FOREACH(callbacks, f, bus->filter_callbacks) {
3140                 if (f->callback == callback && f->userdata == userdata) {
3141                         bus->filter_callbacks_modified = true;
3142                         LIST_REMOVE(struct filter_callback, callbacks, bus->filter_callbacks, f);
3143                         free(f);
3144                         return 1;
3145                 }
3146         }
3147
3148         return 0;
3149 }
3150
3151 static struct node *bus_node_allocate(sd_bus *bus, const char *path) {
3152         struct node *n, *parent;
3153         const char *e;
3154         char *s, *p;
3155         int r;
3156
3157         assert(bus);
3158         assert(path);
3159         assert(path[0] == '/');
3160
3161         n = hashmap_get(bus->nodes, path);
3162         if (n)
3163                 return n;
3164
3165         r = hashmap_ensure_allocated(&bus->nodes, string_hash_func, string_compare_func);
3166         if (r < 0)
3167                 return NULL;
3168
3169         s = strdup(path);
3170         if (!s)
3171                 return NULL;
3172
3173         if (streq(path, "/"))
3174                 parent = NULL;
3175         else {
3176                 e = strrchr(path, '/');
3177                 assert(e);
3178
3179                 p = strndupa(path, MAX(1, path - e));
3180
3181                 parent = bus_node_allocate(bus, p);
3182                 if (!parent) {
3183                         free(s);
3184                         return NULL;
3185                 }
3186         }
3187
3188         n = new0(struct node, 1);
3189         if (!n)
3190                 return NULL;
3191
3192         n->parent = parent;
3193         n->path = s;
3194
3195         r = hashmap_put(bus->nodes, s, n);
3196         if (r < 0) {
3197                 free(s);
3198                 free(n);
3199                 return NULL;
3200         }
3201
3202         if (parent)
3203                 LIST_PREPEND(struct node, siblings, parent->child, n);
3204
3205         return n;
3206 }
3207
3208 static void bus_node_gc(sd_bus *b, struct node *n) {
3209         assert(b);
3210
3211         if (!n)
3212                 return;
3213
3214         if (n->child ||
3215             n->callbacks ||
3216             n->vtables ||
3217             n->enumerators ||
3218             n->object_manager)
3219                 return;
3220
3221         assert(hashmap_remove(b->nodes, n->path) == n);
3222
3223         if (n->parent)
3224                 LIST_REMOVE(struct node, siblings, n->parent->child, n);
3225
3226         free(n->path);
3227         bus_node_gc(b, n->parent);
3228         free(n);
3229 }
3230
3231 static int bus_add_object(
3232                 sd_bus *b,
3233                 bool fallback,
3234                 const char *path,
3235                 sd_bus_message_handler_t callback,
3236                 void *userdata) {
3237
3238         struct node_callback *c;
3239         struct node *n;
3240         int r;
3241
3242         if (!b)
3243                 return -EINVAL;
3244         if (!object_path_is_valid(path))
3245                 return -EINVAL;
3246         if (!callback)
3247                 return -EINVAL;
3248         if (bus_pid_changed(b))
3249                 return -ECHILD;
3250
3251         n = bus_node_allocate(b, path);
3252         if (!n)
3253                 return -ENOMEM;
3254
3255         c = new0(struct node_callback, 1);
3256         if (!c) {
3257                 r = -ENOMEM;
3258                 goto fail;
3259         }
3260
3261         c->node = n;
3262         c->callback = callback;
3263         c->userdata = userdata;
3264         c->is_fallback = fallback;
3265
3266         LIST_PREPEND(struct node_callback, callbacks, n->callbacks, c);
3267         return 0;
3268
3269 fail:
3270         free(c);
3271         bus_node_gc(b, n);
3272         return r;
3273 }
3274
3275 static int bus_remove_object(
3276                 sd_bus *bus,
3277                 bool fallback,
3278                 const char *path,
3279                 sd_bus_message_handler_t callback,
3280                 void *userdata) {
3281
3282         struct node_callback *c;
3283         struct node *n;
3284
3285         if (!bus)
3286                 return -EINVAL;
3287         if (!object_path_is_valid(path))
3288                 return -EINVAL;
3289         if (!callback)
3290                 return -EINVAL;
3291         if (bus_pid_changed(bus))
3292                 return -ECHILD;
3293
3294         n = hashmap_get(bus->nodes, path);
3295         if (!n)
3296                 return 0;
3297
3298         LIST_FOREACH(callbacks, c, n->callbacks)
3299                 if (c->callback == callback && c->userdata == userdata && c->is_fallback == fallback)
3300                         break;
3301         if (!c)
3302                 return 0;
3303
3304         LIST_REMOVE(struct node_callback, callbacks, n->callbacks, c);
3305         free(c);
3306
3307         bus_node_gc(bus, n);
3308
3309         return 1;
3310 }
3311
3312 int sd_bus_add_object(sd_bus *bus, const char *path, sd_bus_message_handler_t callback, void *userdata) {
3313         return bus_add_object(bus, false, path, callback, userdata);
3314 }
3315
3316 int sd_bus_remove_object(sd_bus *bus, const char *path, sd_bus_message_handler_t callback, void *userdata) {
3317         return bus_remove_object(bus, false, path, callback, userdata);
3318 }
3319
3320 int sd_bus_add_fallback(sd_bus *bus, const char *prefix, sd_bus_message_handler_t callback, void *userdata) {
3321         return bus_add_object(bus, true, prefix, callback, userdata);
3322 }
3323
3324 int sd_bus_remove_fallback(sd_bus *bus, const char *prefix, sd_bus_message_handler_t callback, void *userdata) {
3325         return bus_remove_object(bus, true, prefix, callback, userdata);
3326 }
3327
3328 int sd_bus_add_match(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata) {
3329         struct bus_match_component *components = NULL;
3330         unsigned n_components = 0;
3331         uint64_t cookie = 0;
3332         int r = 0;
3333
3334         if (!bus)
3335                 return -EINVAL;
3336         if (!match)
3337                 return -EINVAL;
3338         if (bus_pid_changed(bus))
3339                 return -ECHILD;
3340
3341         r = bus_match_parse(match, &components, &n_components);
3342         if (r < 0)
3343                 goto finish;
3344
3345         if (bus->bus_client) {
3346                 cookie = ++bus->match_cookie;
3347
3348                 r = bus_add_match_internal(bus, match, components, n_components, cookie);
3349                 if (r < 0)
3350                         goto finish;
3351         }
3352
3353         bus->match_callbacks_modified = true;
3354         r = bus_match_add(&bus->match_callbacks, components, n_components, callback, userdata, cookie, NULL);
3355         if (r < 0) {
3356                 if (bus->bus_client)
3357                         bus_remove_match_internal(bus, match, cookie);
3358         }
3359
3360 finish:
3361         bus_match_parse_free(components, n_components);
3362         return r;
3363 }
3364
3365 int sd_bus_remove_match(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata) {
3366         struct bus_match_component *components = NULL;
3367         unsigned n_components = 0;
3368         int r = 0, q = 0;
3369         uint64_t cookie = 0;
3370
3371         if (!bus)
3372                 return -EINVAL;
3373         if (!match)
3374                 return -EINVAL;
3375         if (bus_pid_changed(bus))
3376                 return -ECHILD;
3377
3378         r = bus_match_parse(match, &components, &n_components);
3379         if (r < 0)
3380                 return r;
3381
3382         bus->match_callbacks_modified = true;
3383         r = bus_match_remove(&bus->match_callbacks, components, n_components, callback, userdata, &cookie);
3384
3385         if (bus->bus_client)
3386                 q = bus_remove_match_internal(bus, match, cookie);
3387
3388         bus_match_parse_free(components, n_components);
3389
3390         return r < 0 ? r : q;
3391 }
3392
3393 int sd_bus_emit_signal(
3394                 sd_bus *bus,
3395                 const char *path,
3396                 const char *interface,
3397                 const char *member,
3398                 const char *types, ...) {
3399
3400         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3401         int r;
3402
3403         if (!bus)
3404                 return -EINVAL;
3405         if (!BUS_IS_OPEN(bus->state))
3406                 return -ENOTCONN;
3407         if (bus_pid_changed(bus))
3408                 return -ECHILD;
3409
3410         r = sd_bus_message_new_signal(bus, path, interface, member, &m);
3411         if (r < 0)
3412                 return r;
3413
3414         if (!isempty(types)) {
3415                 va_list ap;
3416
3417                 va_start(ap, types);
3418                 r = bus_message_append_ap(m, types, ap);
3419                 va_end(ap);
3420                 if (r < 0)
3421                         return r;
3422         }
3423
3424         return sd_bus_send(bus, m, NULL);
3425 }
3426
3427 int sd_bus_call_method(
3428                 sd_bus *bus,
3429                 const char *destination,
3430                 const char *path,
3431                 const char *interface,
3432                 const char *member,
3433                 sd_bus_error *error,
3434                 sd_bus_message **reply,
3435                 const char *types, ...) {
3436
3437         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3438         int r;
3439
3440         if (!bus)
3441
3442                 return -EINVAL;
3443         if (!BUS_IS_OPEN(bus->state))
3444                 return -ENOTCONN;
3445         if (bus_pid_changed(bus))
3446                 return -ECHILD;
3447
3448         r = sd_bus_message_new_method_call(bus, destination, path, interface, member, &m);
3449         if (r < 0)
3450                 return r;
3451
3452         if (!isempty(types)) {
3453                 va_list ap;
3454
3455                 va_start(ap, types);
3456                 r = bus_message_append_ap(m, types, ap);
3457                 va_end(ap);
3458                 if (r < 0)
3459                         return r;
3460         }
3461
3462         return sd_bus_send_with_reply_and_block(bus, m, 0, error, reply);
3463 }
3464
3465 int sd_bus_reply_method_return(
3466                 sd_bus *bus,
3467                 sd_bus_message *call,
3468                 const char *types, ...) {
3469
3470         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3471         int r;
3472
3473         if (!bus)
3474                 return -EINVAL;
3475         if (!call)
3476                 return -EINVAL;
3477         if (!call->sealed)
3478                 return -EPERM;
3479         if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
3480                 return -EINVAL;
3481         if (!BUS_IS_OPEN(bus->state))
3482                 return -ENOTCONN;
3483         if (bus_pid_changed(bus))
3484                 return -ECHILD;
3485
3486         if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
3487                 return 0;
3488
3489         r = sd_bus_message_new_method_return(bus, call, &m);
3490         if (r < 0)
3491                 return r;
3492
3493         if (!isempty(types)) {
3494                 va_list ap;
3495
3496                 va_start(ap, types);
3497                 r = bus_message_append_ap(m, types, ap);
3498                 va_end(ap);
3499                 if (r < 0)
3500                         return r;
3501         }
3502
3503         return sd_bus_send(bus, m, NULL);
3504 }
3505
3506 int sd_bus_reply_method_error(
3507                 sd_bus *bus,
3508                 sd_bus_message *call,
3509                 const sd_bus_error *e) {
3510
3511         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3512         int r;
3513
3514         if (!bus)
3515                 return -EINVAL;
3516         if (!call)
3517                 return -EINVAL;
3518         if (!call->sealed)
3519                 return -EPERM;
3520         if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
3521                 return -EINVAL;
3522         if (!sd_bus_error_is_set(e))
3523                 return -EINVAL;
3524         if (!BUS_IS_OPEN(bus->state))
3525                 return -ENOTCONN;
3526         if (bus_pid_changed(bus))
3527                 return -ECHILD;
3528
3529         if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
3530                 return 0;
3531
3532         r = sd_bus_message_new_method_error(bus, call, e, &m);
3533         if (r < 0)
3534                 return r;
3535
3536         return sd_bus_send(bus, m, NULL);
3537 }
3538
3539 int sd_bus_reply_method_errorf(
3540                 sd_bus *bus,
3541                 sd_bus_message *call,
3542                 const char *name,
3543                 const char *format,
3544                 ...) {
3545
3546         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3547         char *n, *m;
3548         va_list ap;
3549         int r;
3550
3551         n = strdup(name);
3552         if (!n)
3553                 return -ENOMEM;
3554
3555         if (format) {
3556                 va_start(ap, format);
3557                 r = vasprintf(&m, format, ap);
3558                 va_end(ap);
3559
3560                 if (r < 0) {
3561                         free(n);
3562                         return -ENOMEM;
3563                 }
3564         }
3565
3566         error.name = n;
3567         error.message = m;
3568         error.need_free = true;
3569
3570         return sd_bus_reply_method_error(bus, call, &error);
3571 }
3572
3573 bool bus_pid_changed(sd_bus *bus) {
3574         assert(bus);
3575
3576         /* We don't support people creating a bus connection and
3577          * keeping it around over a fork(). Let's complain. */
3578
3579         return bus->original_pid != getpid();
3580 }
3581
3582 static void free_node_vtable(sd_bus *bus, struct node_vtable *w) {
3583         assert(bus);
3584
3585         if (!w)
3586                 return;
3587
3588         if (w->interface && w->node && w->vtable) {
3589                 const sd_bus_vtable *v;
3590
3591                 for (v = w->vtable; v->type != _SD_BUS_VTABLE_END; w++) {
3592                         struct vtable_member *x = NULL;
3593
3594                         switch (v->type) {
3595
3596                         case _SD_BUS_VTABLE_METHOD: {
3597                                 struct vtable_member key;
3598
3599                                 key.path = w->node->path;
3600                                 key.interface = w->interface;
3601                                 key.member = v->method.member;
3602
3603                                 x = hashmap_remove(bus->vtable_methods, &key);
3604                                 break;
3605                         }
3606
3607                         case _SD_BUS_VTABLE_PROPERTY:
3608                         case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
3609                                 struct vtable_member key;
3610
3611                                 key.path = w->node->path;
3612                                 key.interface = w->interface;
3613                                 key.member = v->property.member;
3614                                 x = hashmap_remove(bus->vtable_properties, &key);
3615                                 break;
3616                         }}
3617
3618                         free(x);
3619                 }
3620         }
3621
3622         free(w->interface);
3623         free(w);
3624 }
3625
3626 static unsigned vtable_member_hash_func(const void *a) {
3627         const struct vtable_member *m = a;
3628
3629         return
3630                 string_hash_func(m->path) ^
3631                 string_hash_func(m->interface) ^
3632                 string_hash_func(m->member);
3633 }
3634
3635 static int vtable_member_compare_func(const void *a, const void *b) {
3636         const struct vtable_member *x = a, *y = b;
3637         int r;
3638
3639         r = strcmp(x->path, y->path);
3640         if (r != 0)
3641                 return r;
3642
3643         r = strcmp(x->interface, y->interface);
3644         if (r != 0)
3645                 return r;
3646
3647         return strcmp(x->member, y->member);
3648 }
3649
3650 static int add_object_vtable_internal(
3651                 sd_bus *bus,
3652                 const char *path,
3653                 const char *interface,
3654                 const sd_bus_vtable *vtable,
3655                 bool fallback,
3656                 sd_bus_object_find_t find,
3657                 void *userdata) {
3658
3659         struct node_vtable *c = NULL, *i;
3660         const sd_bus_vtable *v;
3661         struct node *n;
3662         int r;
3663
3664         if (!bus)
3665                 return -EINVAL;
3666         if (!object_path_is_valid(path))
3667                 return -EINVAL;
3668         if (!interface_name_is_valid(interface))
3669                 return -EINVAL;
3670         if (!vtable || vtable[0].type != _SD_BUS_VTABLE_START || vtable[0].start.element_size != sizeof(struct sd_bus_vtable))
3671                 return -EINVAL;
3672         if (bus_pid_changed(bus))
3673                 return -ECHILD;
3674
3675         r = hashmap_ensure_allocated(&bus->vtable_methods, vtable_member_hash_func, vtable_member_compare_func);
3676         if (r < 0)
3677                 return r;
3678
3679         r = hashmap_ensure_allocated(&bus->vtable_properties, vtable_member_hash_func, vtable_member_compare_func);
3680         if (r < 0)
3681                 return r;
3682
3683         n = bus_node_allocate(bus, path);
3684         if (!n)
3685                 return -ENOMEM;
3686
3687         LIST_FOREACH(vtables, i, n->vtables) {
3688                 if (streq(i->interface, interface)) {
3689                         r = -EEXIST;
3690                         goto fail;
3691                 }
3692
3693                 if (i->is_fallback != fallback) {
3694                         r = -EPROTOTYPE;
3695                         goto fail;
3696                 }
3697         }
3698
3699         c = new0(struct node_vtable, 1);
3700         if (!c) {
3701                 r = -ENOMEM;
3702                 goto fail;
3703         }
3704
3705         c->node = n;
3706         c->is_fallback = fallback;
3707         c->vtable = vtable;
3708         c->userdata = userdata;
3709         c->find = find;
3710
3711         c->interface = strdup(interface);
3712         if (!c->interface) {
3713                 r = -ENOMEM;
3714                 goto fail;
3715         }
3716
3717         for (v = c->vtable+1; v->type != _SD_BUS_VTABLE_END; v++) {
3718
3719                 switch (v->type) {
3720
3721                 case _SD_BUS_VTABLE_METHOD: {
3722                         struct vtable_member *m;
3723
3724                         if (!member_name_is_valid(v->method.member) ||
3725                             !signature_is_valid(v->method.signature, false) ||
3726                             !signature_is_valid(v->method.result, false) ||
3727                             !v->method.handler ||
3728                             v->flags & (SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY)) {
3729                                 r = -EINVAL;
3730                                 goto fail;
3731                         }
3732
3733                         m = new0(struct vtable_member, 1);
3734                         if (!m) {
3735                                 r = -ENOMEM;
3736                                 goto fail;
3737                         }
3738
3739                         m->parent = c;
3740                         m->path = n->path;
3741                         m->interface = c->interface;
3742                         m->member = v->method.member;
3743                         m->vtable = v;
3744
3745                         r = hashmap_put(bus->vtable_methods, m, m);
3746                         if (r < 0) {
3747                                 free(m);
3748                                 goto fail;
3749                         }
3750
3751                         break;
3752                 }
3753
3754                 case _SD_BUS_VTABLE_PROPERTY:
3755                 case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
3756                         struct vtable_member *m;
3757
3758                         if (!member_name_is_valid(v->property.member) ||
3759                             !signature_is_single(v->property.signature, false) ||
3760                             v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY ||
3761                             (v->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY && !(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE))) {
3762                                 r = -EINVAL;
3763                                 goto fail;
3764                         }
3765
3766
3767                         m = new0(struct vtable_member, 1);
3768                         if (!m) {
3769                                 r = -ENOMEM;
3770                                 goto fail;
3771                         }
3772
3773                         m->parent = c;
3774                         m->path = n->path;
3775                         m->interface = c->interface;
3776                         m->member = v->property.member;
3777                         m->vtable = v;
3778
3779                         r = hashmap_put(bus->vtable_properties, m, m);
3780                         if (r < 0) {
3781                                 free(m);
3782                                 goto fail;
3783                         }
3784
3785                         break;
3786                 }
3787
3788                 case _SD_BUS_VTABLE_SIGNAL:
3789
3790                         if (!member_name_is_valid(v->signal.member) ||
3791                             !signature_is_single(v->signal.signature, false)) {
3792                                 r = -EINVAL;
3793                                 goto fail;
3794                         }
3795
3796                         break;
3797
3798                 default:
3799                         r = -EINVAL;
3800                         goto fail;
3801                 }
3802         }
3803
3804         LIST_PREPEND(struct node_vtable, vtables, n->vtables, c);
3805         return 0;
3806
3807 fail:
3808         if (c)
3809                 free_node_vtable(bus, c);
3810
3811         bus_node_gc(bus, n);
3812         return 0;
3813 }
3814
3815 static int remove_object_vtable_internal(
3816                 sd_bus *bus,
3817                 const char *path,
3818                 const char *interface,
3819                 bool fallback) {
3820
3821         struct node_vtable *c;
3822         struct node *n;
3823
3824         if (!bus)
3825                 return -EINVAL;
3826         if (!object_path_is_valid(path))
3827                 return -EINVAL;
3828         if (!interface_name_is_valid(interface))
3829                 return -EINVAL;
3830         if (bus_pid_changed(bus))
3831                 return -ECHILD;
3832
3833         n = hashmap_get(bus->nodes, path);
3834         if (!n)
3835                 return 0;
3836
3837         LIST_FOREACH(vtables, c, n->vtables)
3838                 if (streq(c->interface, interface) && c->is_fallback == fallback)
3839                         break;
3840
3841         if (!c)
3842                 return 0;
3843
3844         LIST_REMOVE(struct node_vtable, vtables, n->vtables, c);
3845
3846         free_node_vtable(bus, c);
3847         return 1;
3848 }
3849
3850 int sd_bus_add_object_vtable(
3851                 sd_bus *bus,
3852                 const char *path,
3853                 const char *interface,
3854                 const sd_bus_vtable *vtable,
3855                 void *userdata) {
3856
3857         return add_object_vtable_internal(bus, path, interface, vtable, false, NULL, userdata);
3858 }
3859
3860 int sd_bus_remove_object_vtable(
3861                 sd_bus *bus,
3862                 const char *path,
3863                 const char *interface) {
3864
3865         return remove_object_vtable_internal(bus, path, interface, false);
3866 }
3867
3868 int sd_bus_add_fallback_vtable(
3869                 sd_bus *bus,
3870                 const char *path,
3871                 const char *interface,
3872                 const sd_bus_vtable *vtable,
3873                 sd_bus_object_find_t find,
3874                 void *userdata) {
3875
3876         return add_object_vtable_internal(bus, path, interface, vtable, true, find, userdata);
3877 }
3878
3879 int sd_bus_remove_fallback_vtable(
3880                 sd_bus *bus,
3881                 const char *path,
3882                 const char *interface) {
3883
3884         return remove_object_vtable_internal(bus, path, interface, true);
3885 }
3886
3887 int sd_bus_add_node_enumerator(
3888                 sd_bus *bus,
3889                 const char *path,
3890                 sd_bus_node_enumerator_t callback,
3891                 void *userdata) {
3892
3893         struct node_enumerator *c;
3894         struct node *n;
3895         int r;
3896
3897         if (!bus)
3898                 return -EINVAL;
3899         if (!object_path_is_valid(path))
3900                 return -EINVAL;
3901         if (!callback)
3902                 return -EINVAL;
3903         if (bus_pid_changed(bus))
3904                 return -ECHILD;
3905
3906         n = bus_node_allocate(bus, path);
3907         if (!n)
3908                 return -ENOMEM;
3909
3910         c = new0(struct node_enumerator, 1);
3911         if (!c) {
3912                 r = -ENOMEM;
3913                 goto fail;
3914         }
3915
3916         c->node = n;
3917         c->callback = callback;
3918         c->userdata = userdata;
3919
3920         LIST_PREPEND(struct node_enumerator, enumerators, n->enumerators, c);
3921         return 0;
3922
3923 fail:
3924         free(c);
3925         bus_node_gc(bus, n);
3926         return r;
3927 }
3928
3929 int sd_bus_remove_node_enumerator(
3930                 sd_bus *bus,
3931                 const char *path,
3932                 sd_bus_node_enumerator_t callback,
3933                 void *userdata) {
3934
3935         struct node_enumerator *c;
3936         struct node *n;
3937
3938         if (!bus)
3939                 return -EINVAL;
3940         if (!object_path_is_valid(path))
3941                 return -EINVAL;
3942         if (!callback)
3943                 return -EINVAL;
3944         if (bus_pid_changed(bus))
3945                 return -ECHILD;
3946
3947         n = hashmap_get(bus->nodes, path);
3948         if (!n)
3949                 return 0;
3950
3951         LIST_FOREACH(enumerators, c, n->enumerators)
3952                 if (c->callback == callback && c->userdata == userdata)
3953                         break;
3954
3955         if (!c)
3956                 return 0;
3957
3958         LIST_REMOVE(struct node_enumerator, enumerators, n->enumerators, c);
3959         free(c);
3960
3961         bus_node_gc(bus, n);
3962
3963         return 1;
3964 }
3965
3966 static int emit_properties_changed_on_interface(
3967                 sd_bus *bus,
3968                 const char *prefix,
3969                 const char *path,
3970                 const char *interface,
3971                 bool require_fallback,
3972                 char **names) {
3973
3974         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3975         bool has_invalidating = false;
3976         struct vtable_member key;
3977         struct node_vtable *c;
3978         struct node *n;
3979         char **property;
3980         void *u = NULL;
3981         int r;
3982
3983         assert(bus);
3984         assert(path);
3985         assert(interface);
3986
3987         n = hashmap_get(bus->nodes, prefix);
3988         if (!n)
3989                 return 0;
3990
3991         LIST_FOREACH(vtables, c, n->vtables) {
3992                 if (require_fallback && !c->is_fallback)
3993                         continue;
3994
3995                 if (streq(c->interface, interface))
3996                         break;
3997
3998                 r = node_vtable_get_userdata(bus, path, c, &u);
3999                 if (r < 0)
4000                         return r;
4001                 if (r > 0)
4002                         break;
4003         }
4004
4005         if (!c)
4006                 return 0;
4007
4008         r = sd_bus_message_new_signal(bus, path, "org.freedesktop.DBus", "PropertiesChanged", &m);
4009         if (r < 0)
4010                 return r;
4011
4012         r = sd_bus_message_append(m, "s", interface);
4013         if (r < 0)
4014                 return r;
4015
4016         r = sd_bus_message_open_container(m, 'a', "{sv}");
4017         if (r < 0)
4018                 return r;
4019
4020         key.path = prefix;
4021         key.interface = interface;
4022
4023         STRV_FOREACH(property, names) {
4024                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4025                 struct vtable_member *v;
4026
4027                 key.member = *property;
4028                 v = hashmap_get(bus->vtable_properties, &key);
4029                 if (!v)
4030                         return -ENOENT;
4031
4032                 assert(c == v->parent);
4033
4034                 if (!(v->vtable->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE))
4035                         return -EDOM;
4036                 if (v->vtable->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY) {
4037                         has_invalidating = true;
4038                         continue;
4039                 }
4040
4041                 r = sd_bus_message_open_container(m, 'e', "sv");
4042                 if (r < 0)
4043                         return r;
4044
4045                 r = sd_bus_message_append(m, "s", *n);
4046                 if (r < 0)
4047                         return r;
4048
4049                 r = sd_bus_message_open_container(m, 'v', v->vtable->property.signature);
4050                 if (r < 0)
4051                         return r;
4052
4053                 r = v->vtable->property.get(bus, m->path, interface, *property, m, &error, vtable_property_convert_userdata(v->vtable, u));
4054                 if (r < 0)
4055                         return r;
4056
4057                 if (sd_bus_error_is_set(&error))
4058                         return bus_error_to_errno(&error);
4059
4060                 r = sd_bus_message_close_container(m);
4061                 if (r < 0)
4062                         return r;
4063
4064                 r = sd_bus_message_close_container(m);
4065                 if (r < 0)
4066                         return r;
4067         }
4068
4069         r = sd_bus_message_close_container(m);
4070         if (r < 0)
4071                 return r;
4072
4073         r = sd_bus_message_open_container(m, 'a', "s");
4074         if (r < 0)
4075                 return r;
4076
4077         if (has_invalidating) {
4078                 STRV_FOREACH(property, names) {
4079                         struct vtable_member *v;
4080
4081                         key.member = *property;
4082                         assert_se(v = hashmap_get(bus->vtable_properties, &key));
4083                         assert(c == v->parent);
4084
4085                         if (!(v->vtable->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY))
4086                                 continue;
4087
4088                         r = sd_bus_message_append(m, "s", *property);
4089                         if (r < 0)
4090                                 return r;
4091                 }
4092         }
4093
4094         r = sd_bus_message_close_container(m);
4095         if (r < 0)
4096                 return r;
4097
4098         r = sd_bus_send(bus, m, NULL);
4099         if (r < 0)
4100                 return r;
4101
4102         return 1;
4103 }
4104
4105 int sd_bus_emit_properties_changed_strv(sd_bus *bus, const char *path, const char *interface, char **names) {
4106         size_t pl;
4107         int r;
4108
4109         if (!bus)
4110                 return -EINVAL;
4111         if (!object_path_is_valid(path))
4112                 return -EINVAL;
4113         if (!interface_name_is_valid(interface))
4114                 return -EINVAL;
4115
4116         r = emit_properties_changed_on_interface(bus, path, path, interface, false, names);
4117         if (r != 0)
4118                 return r;
4119
4120         pl = strlen(path);
4121         if (pl > 1 ) {
4122                 char p[pl+1];
4123
4124                 strcpy(p, path);
4125                 for (;;) {
4126                         char *e;
4127
4128                         if (streq(p, "/"))
4129                                 break;
4130
4131                         e = strrchr(p, '/');
4132                         assert(e);
4133                         if (e == p)
4134                                 *(e+1) = 0;
4135                         else
4136                                 *e = 0;
4137
4138                         r = emit_properties_changed_on_interface(bus, p, path, interface, true, names);
4139                         if (r != 0)
4140                                 return r;
4141                 }
4142         }
4143
4144         return -ENOENT;
4145 }
4146
4147 int sd_bus_emit_properties_changed(sd_bus *bus, const char *path, const char *interface, const char *name, ...)  {
4148         _cleanup_strv_free_ char **names = NULL;
4149         va_list ap;
4150
4151         va_start(ap, name);
4152         names = strv_new_ap(name, ap);
4153         va_end(ap);
4154
4155         if (!names)
4156                 return -ENOMEM;
4157
4158         return sd_bus_emit_properties_changed_strv(bus, path, interface, names);
4159 }
4160
4161 int sd_bus_emit_interfaces_added(sd_bus *bus, const char *path, const char *interfaces, ...) {
4162         return -ENOSYS;
4163 }
4164
4165 int sd_bus_emit_interfaces_removed(sd_bus *bus, const char *path, const char *interfaces, ...) {
4166         return -ENOSYS;
4167 }
4168
4169 int sd_bus_get_property(
4170                 sd_bus *bus,
4171                 const char *destination,
4172                 const char *path,
4173                 const char *interface,
4174                 const char *member,
4175                 sd_bus_error *error,
4176                 sd_bus_message **reply,
4177                 const char *type) {
4178
4179         sd_bus_message *rep = NULL;
4180         int r;
4181
4182         if (interface && !interface_name_is_valid(interface))
4183                 return -EINVAL;
4184         if (!member_name_is_valid(member))
4185                 return -EINVAL;
4186         if (!signature_is_single(type, false))
4187                 return -EINVAL;
4188         if (!reply)
4189                 return -EINVAL;
4190
4191         r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &rep, "ss", strempty(interface), member);
4192         if (r < 0)
4193                 return r;
4194
4195         r = sd_bus_message_enter_container(rep, 'v', type);
4196         if (r < 0) {
4197                 sd_bus_message_unref(rep);
4198                 return r;
4199         }
4200
4201         *reply = rep;
4202         return 0;
4203 }
4204
4205 int sd_bus_set_property(
4206                 sd_bus *bus,
4207                 const char *destination,
4208                 const char *path,
4209                 const char *interface,
4210                 const char *member,
4211                 sd_bus_error *error,
4212                 const char *type, ...) {
4213
4214         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4215         va_list ap;
4216         int r;
4217
4218         if (interface && !interface_name_is_valid(interface))
4219                 return -EINVAL;
4220         if (!member_name_is_valid(member))
4221                 return -EINVAL;
4222         if (!signature_is_single(type, false))
4223                 return -EINVAL;
4224
4225         r = sd_bus_message_new_method_call(bus, destination, path, "org.freedesktop.DBus.Properties", "Set", &m);
4226         if (r < 0)
4227                 return r;
4228
4229         r = sd_bus_message_append(m, "ss", strempty(interface), member);
4230         if (r < 0)
4231                 return r;
4232
4233         r = sd_bus_message_open_container(m, 'v', type);
4234         if (r < 0)
4235                 return r;
4236
4237         va_start(ap, type);
4238         r = bus_message_append_ap(m, type, ap);
4239         va_end(ap);
4240         if (r < 0)
4241                 return r;
4242
4243         r = sd_bus_message_close_container(m);
4244         if (r < 0)
4245                 return r;
4246
4247         return sd_bus_send_with_reply_and_block(bus, m, 0, error, NULL);
4248 }
4249
4250 int sd_bus_add_object_manager(sd_bus *bus, const char *path) {
4251         struct node *n;
4252
4253         if (!bus)
4254                 return -EINVAL;
4255         if (!object_path_is_valid(path))
4256                 return -EINVAL;
4257         if (bus_pid_changed(bus))
4258                 return -ECHILD;
4259
4260         n = bus_node_allocate(bus, path);
4261         if (!n)
4262                 return -ENOMEM;
4263
4264         n->object_manager = true;
4265         return 0;
4266 }
4267
4268 int sd_bus_remove_object_manager(sd_bus *bus, const char *path) {
4269         struct node *n;
4270
4271         if (!bus)
4272                 return -EINVAL;
4273         if (!object_path_is_valid(path))
4274                 return -EINVAL;
4275         if (bus_pid_changed(bus))
4276                 return -ECHILD;
4277
4278         n = hashmap_get(bus->nodes, path);
4279         if (!n)
4280                 return 0;
4281
4282         if (!n->object_manager)
4283                 return 0;
4284
4285         n->object_manager = false;
4286         bus_node_gc(bus, n);
4287         return 1;
4288 }