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