chiark / gitweb /
f0de7a32fb53d6b1df8d3b6527cc367de6d32c68
[elogind.git] / src / libsystemd-bus / bus-message.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 <errno.h>
23 #include <fcntl.h>
24
25 #include "util.h"
26 #include "utf8.h"
27 #include "strv.h"
28 #include "time-util.h"
29 #include "cgroup-util.h"
30
31 #include "sd-bus.h"
32 #include "bus-message.h"
33 #include "bus-internal.h"
34 #include "bus-type.h"
35 #include "bus-signature.h"
36
37 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
38
39 static void reset_containers(sd_bus_message *m) {
40         unsigned i;
41
42         assert(m);
43
44         for (i = 0; i < m->n_containers; i++)
45                 free(m->containers[i].signature);
46
47         free(m->containers);
48         m->containers = NULL;
49
50         m->n_containers = 0;
51         m->root_container.index = 0;
52 }
53
54 static void message_free(sd_bus_message *m) {
55         assert(m);
56
57         if (m->free_header)
58                 free(m->header);
59
60         if (m->free_fields)
61                 free(m->fields);
62
63         if (m->free_body)
64                 free(m->body);
65
66         if (m->free_kdbus)
67                 free(m->kdbus);
68
69         if (m->free_fds) {
70                 close_many(m->fds, m->n_fds);
71                 free(m->fds);
72         }
73
74         free(m->cmdline_array);
75
76         reset_containers(m);
77         free(m->root_container.signature);
78
79         free(m->peeked_signature);
80
81         free(m->unit);
82         free(m->user_unit);
83         free(m->session);
84         free(m);
85 }
86
87 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
88         size_t start, n;
89         void *k;
90
91         assert(p);
92         assert(sz);
93         assert(align > 0);
94
95         start = ALIGN_TO((size_t) *sz, align);
96         n = start + extend;
97
98         if (n == *sz)
99                 return (uint8_t*) *p + start;
100
101         if (n > (size_t) ((uint32_t) -1))
102                 return NULL;
103
104         k = realloc(*p, n);
105         if (!k)
106                 return NULL;
107
108         /* Zero out padding */
109         if (start > *sz)
110                 memset((uint8_t*) k + *sz, 0, start - *sz);
111
112         *p = k;
113         *sz = n;
114
115         return (uint8_t*) k + start;
116 }
117
118 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
119         void *p, *o;
120
121         assert(m);
122
123         o = m->fields;
124         p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
125         if (!p)
126                 return NULL;
127
128         if (o != m->fields) {
129                 /* Adjust quick access pointers */
130
131                 if (m->path)
132                         m->path = (const char*) m->fields + (m->path - (const char*) o);
133                 if (m->interface)
134                         m->interface = (const char*) m->fields + (m->interface - (const char*) o);
135                 if (m->member)
136                         m->member = (const char*) m->fields + (m->member - (const char*) o);
137                 if (m->destination)
138                         m->destination = (const char*) m->fields + (m->destination - (const char*) o);
139                 if (m->sender)
140                         m->sender = (const char*) m->fields + (m->sender - (const char*) o);
141                 if (m->error.name)
142                         m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
143         }
144
145         m->free_fields = true;
146
147         return p;
148 }
149
150 static int message_append_field_string(
151                 sd_bus_message *m,
152                 uint8_t h,
153                 char type,
154                 const char *s,
155                 const char **ret) {
156
157         size_t l;
158         uint8_t *p;
159
160         assert(m);
161
162         l = strlen(s);
163         if (l > (size_t) (uint32_t) -1)
164                 return -EINVAL;
165
166         /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
167         p = message_extend_fields(m, 8, 4 + 4 + l + 1);
168         if (!p)
169                 return -ENOMEM;
170
171         p[0] = h;
172         p[1] = 1;
173         p[2] = type;
174         p[3] = 0;
175
176         ((uint32_t*) p)[1] = l;
177         memcpy(p + 8, s, l + 1);
178
179         if (ret)
180                 *ret = (const char*) p + 8;
181
182         return 0;
183 }
184
185 static int message_append_field_signature(
186                 sd_bus_message *m,
187                 uint8_t h,
188                 const char *s,
189                 const char **ret) {
190
191         size_t l;
192         uint8_t *p;
193
194         assert(m);
195
196         l = strlen(s);
197         if (l > 255)
198                 return -EINVAL;
199
200         /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
201         p = message_extend_fields(m, 8, 4 + 1 + l + 1);
202         if (!p)
203                 return -ENOMEM;
204
205         p[0] = h;
206         p[1] = 1;
207         p[2] = SD_BUS_TYPE_SIGNATURE;
208         p[3] = 0;
209         p[4] = l;
210         memcpy(p + 5, s, l + 1);
211
212         if (ret)
213                 *ret = (const char*) p + 5;
214
215         return 0;
216 }
217
218 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
219         uint8_t *p;
220
221         assert(m);
222
223         /* field id byte + signature length + signature 'u' + NUL + value */
224         p = message_extend_fields(m, 8, 4 + 4);
225         if (!p)
226                 return -ENOMEM;
227
228         p[0] = h;
229         p[1] = 1;
230         p[2] = SD_BUS_TYPE_UINT32;
231         p[3] = 0;
232
233         ((uint32_t*) p)[1] = x;
234
235         return 0;
236 }
237
238 int bus_message_from_header(
239                 void *buffer,
240                 size_t length,
241                 int *fds,
242                 unsigned n_fds,
243                 const struct ucred *ucred,
244                 const char *label,
245                 size_t extra,
246                 sd_bus_message **ret) {
247
248         sd_bus_message *m;
249         struct bus_header *h;
250         size_t a, label_sz;
251
252         assert(buffer || length <= 0);
253         assert(fds || n_fds <= 0);
254         assert(ret);
255
256         if (length < sizeof(struct bus_header))
257                 return -EBADMSG;
258
259         h = buffer;
260         if (h->version != 1)
261                 return -EBADMSG;
262
263         if (h->serial == 0)
264                 return -EBADMSG;
265
266         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
267                 return -EBADMSG;
268
269         if (h->endian != SD_BUS_LITTLE_ENDIAN &&
270             h->endian != SD_BUS_BIG_ENDIAN)
271                 return -EBADMSG;
272
273         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
274
275         if (label) {
276                 label_sz = strlen(label);
277                 a += label_sz + 1;
278         }
279
280         m = malloc0(a);
281         if (!m)
282                 return -ENOMEM;
283
284         m->n_ref = 1;
285         m->sealed = true;
286         m->header = h;
287         m->fds = fds;
288         m->n_fds = n_fds;
289
290         if (ucred) {
291                 m->uid = ucred->uid;
292                 m->pid = ucred->pid;
293                 m->gid = ucred->gid;
294                 m->uid_valid = m->gid_valid = true;
295         }
296
297         if (label) {
298                 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
299                 memcpy(m->label, label, label_sz + 1);
300         }
301
302         *ret = m;
303         return 0;
304 }
305
306 int bus_message_from_malloc(
307                 void *buffer,
308                 size_t length,
309                 int *fds,
310                 unsigned n_fds,
311                 const struct ucred *ucred,
312                 const char *label,
313                 sd_bus_message **ret) {
314
315         sd_bus_message *m;
316         int r;
317
318         r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
319         if (r < 0)
320                 return r;
321
322         if (length != BUS_MESSAGE_SIZE(m)) {
323                 r = -EBADMSG;
324                 goto fail;
325         }
326
327         m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
328         m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
329
330         m->n_iovec = 1;
331         m->iovec[0].iov_base = buffer;
332         m->iovec[0].iov_len = length;
333
334         r = bus_message_parse_fields(m);
335         if (r < 0)
336                 goto fail;
337
338         /* We take possession of the memory and fds now */
339         m->free_header = true;
340         m->free_fds = true;
341
342         *ret = m;
343         return 0;
344
345 fail:
346         message_free(m);
347         return r;
348 }
349
350 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
351         sd_bus_message *m;
352
353         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
354         if (!m)
355                 return NULL;
356
357         m->n_ref = 1;
358         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
359         m->header->endian = SD_BUS_NATIVE_ENDIAN;
360         m->header->type = type;
361         m->header->version = bus ? bus->message_version : 1;
362         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
363
364         return m;
365 }
366
367 int sd_bus_message_new_signal(
368                 sd_bus *bus,
369                 const char *path,
370                 const char *interface,
371                 const char *member,
372                 sd_bus_message **m) {
373
374         sd_bus_message *t;
375         int r;
376
377         if (!path)
378                 return -EINVAL;
379         if (!interface)
380                 return -EINVAL;
381         if (!member)
382                 return -EINVAL;
383         if (!m)
384                 return -EINVAL;
385         if (bus && bus->state == BUS_UNSET)
386                 return -ENOTCONN;
387
388         t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
389         if (!t)
390                 return -ENOMEM;
391
392         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
393
394         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
395         if (r < 0)
396                 goto fail;
397         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
398         if (r < 0)
399                 goto fail;
400         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
401         if (r < 0)
402                 goto fail;
403
404         *m = t;
405         return 0;
406
407 fail:
408         sd_bus_message_unref(t);
409         return r;
410 }
411
412 int sd_bus_message_new_method_call(
413                 sd_bus *bus,
414                 const char *destination,
415                 const char *path,
416                 const char *interface,
417                 const char *member,
418                 sd_bus_message **m) {
419
420         sd_bus_message *t;
421         int r;
422
423         if (!path)
424                 return -EINVAL;
425         if (!member)
426                 return -EINVAL;
427         if (!m)
428                 return -EINVAL;
429         if (bus && bus->state == BUS_UNSET)
430                 return -ENOTCONN;
431
432         t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
433         if (!t)
434                 return -ENOMEM;
435
436         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
437         if (r < 0)
438                 goto fail;
439         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
440         if (r < 0)
441                 goto fail;
442
443         if (interface) {
444                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
445                 if (r < 0)
446                         goto fail;
447         }
448
449         if (destination) {
450                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
451                 if (r < 0)
452                         goto fail;
453         }
454
455         *m = t;
456         return 0;
457
458 fail:
459         message_free(t);
460         return r;
461 }
462
463 static int message_new_reply(
464                 sd_bus *bus,
465                 sd_bus_message *call,
466                 uint8_t type,
467                 sd_bus_message **m) {
468
469         sd_bus_message *t;
470         int r;
471
472         if (!call)
473                 return -EINVAL;
474         if (!call->sealed)
475                 return -EPERM;
476         if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
477                 return -EINVAL;
478         if (!m)
479                 return -EINVAL;
480         if (bus && bus->state == BUS_UNSET)
481                 return -ENOTCONN;
482
483         t = message_new(bus, type);
484         if (!t)
485                 return -ENOMEM;
486
487         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
488         t->reply_serial = BUS_MESSAGE_SERIAL(call);
489
490         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
491         if (r < 0)
492                 goto fail;
493
494         if (call->sender) {
495                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
496                 if (r < 0)
497                         goto fail;
498         }
499
500         t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
501
502         *m = t;
503         return 0;
504
505 fail:
506         message_free(t);
507         return r;
508 }
509
510 int sd_bus_message_new_method_return(
511                 sd_bus *bus,
512                 sd_bus_message *call,
513                 sd_bus_message **m) {
514
515         return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
516 }
517
518 int sd_bus_message_new_method_error(
519                 sd_bus *bus,
520                 sd_bus_message *call,
521                 const sd_bus_error *e,
522                 sd_bus_message **m) {
523
524         sd_bus_message *t;
525         int r;
526
527         if (!sd_bus_error_is_set(e))
528                 return -EINVAL;
529         if (!m)
530                 return -EINVAL;
531
532         r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
533         if (r < 0)
534                 return r;
535
536         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
537         if (r < 0)
538                 goto fail;
539
540         if (e->message) {
541                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
542                 if (r < 0)
543                         goto fail;
544         }
545
546         *m = t;
547         return 0;
548
549 fail:
550         message_free(t);
551         return r;
552 }
553
554 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
555         if (!m)
556                 return NULL;
557
558         assert(m->n_ref > 0);
559         m->n_ref++;
560
561         return m;
562 }
563
564 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
565         if (!m)
566                 return NULL;
567
568         assert(m->n_ref > 0);
569         m->n_ref--;
570
571         if (m->n_ref <= 0)
572                 message_free(m);
573
574         return NULL;
575 }
576
577 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
578         if (!m)
579                 return -EINVAL;
580         if (!type)
581                 return -EINVAL;
582
583         *type = m->header->type;
584         return 0;
585 }
586
587 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
588         if (!m)
589                 return -EINVAL;
590         if (!serial)
591                 return -EINVAL;
592         if (m->header->serial == 0)
593                 return -ENOENT;
594
595         *serial = BUS_MESSAGE_SERIAL(m);
596         return 0;
597 }
598
599 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
600         if (!m)
601                 return -EINVAL;
602         if (!serial)
603                 return -EINVAL;
604         if (m->reply_serial == 0)
605                 return -ENOENT;
606
607         *serial = m->reply_serial;
608         return 0;
609 }
610
611 int sd_bus_message_get_no_reply(sd_bus_message *m) {
612         if (!m)
613                 return -EINVAL;
614
615         return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
616 }
617
618 const char *sd_bus_message_get_path(sd_bus_message *m) {
619         if (!m)
620                 return NULL;
621
622         return m->path;
623 }
624
625 const char *sd_bus_message_get_interface(sd_bus_message *m) {
626         if (!m)
627                 return NULL;
628
629         return m->interface;
630 }
631
632 const char *sd_bus_message_get_member(sd_bus_message *m) {
633         if (!m)
634                 return NULL;
635
636         return m->member;
637 }
638 const char *sd_bus_message_get_destination(sd_bus_message *m) {
639         if (!m)
640                 return NULL;
641
642         return m->destination;
643 }
644
645 const char *sd_bus_message_get_sender(sd_bus_message *m) {
646         if (!m)
647                 return NULL;
648
649         return m->sender;
650 }
651
652 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
653         if (!m)
654                 return NULL;
655
656         if (!sd_bus_error_is_set(&m->error))
657                 return NULL;
658
659         return &m->error;
660 }
661
662 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
663         if (!m)
664                 return -EINVAL;
665         if (!uid)
666                 return -EINVAL;
667         if (!m->uid_valid)
668                 return -ESRCH;
669
670         *uid = m->uid;
671         return 0;
672 }
673
674 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
675         if (!m)
676                 return -EINVAL;
677         if (!gid)
678                 return -EINVAL;
679         if (!m->gid_valid)
680                 return -ESRCH;
681
682         *gid = m->gid;
683         return 0;
684 }
685
686 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
687         if (!m)
688                 return -EINVAL;
689         if (!pid)
690                 return -EINVAL;
691         if (m->pid <= 0)
692                 return -ESRCH;
693
694         *pid = m->pid;
695         return 0;
696 }
697
698 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
699         if (!m)
700                 return -EINVAL;
701         if (!tid)
702                 return -EINVAL;
703         if (m->tid <= 0)
704                 return -ESRCH;
705
706         *tid = m->tid;
707         return 0;
708 }
709
710 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
711         if (!m)
712                 return -EINVAL;
713         if (!usec)
714                 return -EINVAL;
715         if (m->pid_starttime <= 0)
716                 return -ESRCH;
717
718         *usec = m->pid_starttime;
719         return 0;
720 }
721
722 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
723         if (!m)
724                 return -EINVAL;
725         if (!m->label)
726                 return -ESRCH;
727
728         *ret = m->label;
729         return 0;
730 }
731
732 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
733         if (!m)
734                 return -EINVAL;
735         if (!usec)
736                 return -EINVAL;
737         if (m->monotonic <= 0)
738                 return -ESRCH;
739
740         *usec = m->monotonic;
741         return 0;
742 }
743
744 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
745         if (!m)
746                 return -EINVAL;
747         if (!usec)
748                 return -EINVAL;
749         if (m->realtime <= 0)
750                 return -ESRCH;
751
752         *usec = m->realtime;
753         return 0;
754 }
755
756 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
757         if (!m)
758                 return -EINVAL;
759         if (!ret)
760                 return -EINVAL;
761         if (!m->comm)
762                 return -ESRCH;
763
764         *ret = m->comm;
765         return 0;
766 }
767
768 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
769         if (!m)
770                 return -EINVAL;
771         if (!ret)
772                 return -EINVAL;
773         if (!m->tid_comm)
774                 return -ESRCH;
775
776         *ret = m->tid_comm;
777         return 0;
778 }
779
780 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
781         if (!m)
782                 return -EINVAL;
783         if (!ret)
784                 return -EINVAL;
785         if (!m->exe)
786                 return -ESRCH;
787
788         *ret = m->exe;
789         return 0;
790 }
791
792 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
793         if (!m)
794                 return -EINVAL;
795         if (!ret)
796                 return -EINVAL;
797         if (!m->cgroup)
798                 return -ESRCH;
799
800         *ret = m->cgroup;
801         return 0;
802 }
803
804 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
805         int r;
806
807         if (!m)
808                 return -EINVAL;
809         if (!ret)
810                 return -EINVAL;
811         if (!m->cgroup)
812                 return -ESRCH;
813
814         if (!m->unit) {
815                 r = cg_path_get_unit(m->cgroup, &m->unit);
816                 if (r < 0)
817                         return r;
818         }
819
820         *ret = m->unit;
821         return 0;
822 }
823
824 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
825         int r;
826
827         if (!m)
828                 return -EINVAL;
829         if (!ret)
830                 return -EINVAL;
831         if (!m->cgroup)
832                 return -ESRCH;
833
834         if (!m->user_unit) {
835                 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
836                 if (r < 0)
837                         return r;
838         }
839
840         *ret = m->user_unit;
841         return 0;
842 }
843
844 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
845         int r;
846
847         if (!m)
848                 return -EINVAL;
849         if (!ret)
850                 return -EINVAL;
851         if (!m->cgroup)
852                 return -ESRCH;
853
854         if (!m->session) {
855                 r = cg_path_get_session(m->cgroup, &m->session);
856                 if (r < 0)
857                         return r;
858         }
859
860         *ret = m->session;
861         return 0;
862 }
863
864 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
865         if (!m)
866                 return -EINVAL;
867         if (!uid)
868                 return -EINVAL;
869         if (!m->cgroup)
870                 return -ESRCH;
871
872         return cg_path_get_owner_uid(m->cgroup, uid);
873 }
874
875 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
876         size_t n, i;
877         const char *p;
878         bool first;
879
880         if (!m)
881                 return -EINVAL;
882
883         if (!m->cmdline)
884                 return -ENOENT;
885
886         for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
887                 if (*p == 0)
888                         n++;
889
890         m->cmdline_array = new(char*, n + 1);
891         if (!m->cmdline_array)
892                 return -ENOMEM;
893
894         for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
895                 if (first)
896                         m->cmdline_array[i++] = (char*) p;
897
898                 first = *p == 0;
899         }
900
901         m->cmdline_array[i] = NULL;
902         *cmdline = m->cmdline_array;
903
904         return 0;
905 }
906
907 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
908         if (!m)
909                 return -EINVAL;
910
911         if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
912                 return 0;
913
914         if (interface && (!m->interface || !streq(m->interface, interface)))
915                 return 0;
916
917         if (member &&  (!m->member || !streq(m->member, member)))
918                 return 0;
919
920         return 1;
921 }
922
923 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
924         if (!m)
925                 return -EINVAL;
926
927         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
928                 return 0;
929
930         if (interface && (!m->interface || !streq(m->interface, interface)))
931                 return 0;
932
933         if (member &&  (!m->member || !streq(m->member, member)))
934                 return 0;
935
936         return 1;
937 }
938
939 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
940         if (!m)
941                 return -EINVAL;
942
943         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
944                 return 0;
945
946         if (name && (!m->error.name || !streq(m->error.name, name)))
947                 return 0;
948
949         return 1;
950 }
951
952 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
953         if (!m)
954                 return -EINVAL;
955         if (m->sealed)
956                 return -EPERM;
957         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
958                 return -EPERM;
959
960         if (b)
961                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
962         else
963                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
964
965         return 0;
966 }
967
968 static struct bus_container *message_get_container(sd_bus_message *m) {
969         assert(m);
970
971         if (m->n_containers == 0)
972                 return &m->root_container;
973
974         assert(m->containers);
975         return m->containers + m->n_containers - 1;
976 }
977
978 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
979         void *p, *o;
980         size_t added;
981         struct bus_container *c;
982
983         assert(m);
984         assert(align > 0);
985
986         o = m->body;
987         added = m->header->body_size;
988
989         p = buffer_extend(&m->body, &m->header->body_size, align, sz);
990         if (!p)
991                 return NULL;
992
993         added = m->header->body_size - added;
994
995         for (c = m->containers; c < m->containers + m->n_containers; c++)
996                 if (c->array_size) {
997                         c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
998                         *c->array_size += added;
999                 }
1000
1001         if (o != m->body) {
1002                 if (m->error.message)
1003                         m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
1004         }
1005
1006         m->free_body = true;
1007
1008         return p;
1009 }
1010
1011 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1012         struct bus_container *c;
1013         ssize_t align, sz;
1014         uint32_t k;
1015         void *a;
1016         char *e = NULL;
1017         int fd = -1;
1018         uint32_t fdi = 0;
1019         int r;
1020
1021         if (!m)
1022                 return -EINVAL;
1023         if (!p)
1024                 return -EINVAL;
1025         if (m->sealed)
1026                 return -EPERM;
1027         if (!bus_type_is_basic(type))
1028                 return -EINVAL;
1029
1030         c = message_get_container(m);
1031
1032         if (c->signature && c->signature[c->index]) {
1033                 /* Container signature is already set */
1034
1035                 if (c->signature[c->index] != type)
1036                         return -ENXIO;
1037         } else {
1038                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1039                 if (c->enclosing != 0)
1040                         return -ENXIO;
1041
1042                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1043                 if (!e)
1044                         return -ENOMEM;
1045         }
1046
1047         switch (type) {
1048
1049         case SD_BUS_TYPE_STRING:
1050         case SD_BUS_TYPE_OBJECT_PATH:
1051
1052                 align = 4;
1053                 sz = 4 + strlen(p) + 1;
1054                 break;
1055
1056         case SD_BUS_TYPE_SIGNATURE:
1057
1058                 align = 1;
1059                 sz = 1 + strlen(p) + 1;
1060                 break;
1061
1062         case SD_BUS_TYPE_BOOLEAN:
1063                 align = sz = 4;
1064
1065                 assert_cc(sizeof(int) == sizeof(uint32_t));
1066                 memcpy(&k, p, 4);
1067                 k = !!k;
1068                 p = &k;
1069                 break;
1070
1071         case SD_BUS_TYPE_UNIX_FD: {
1072                 int z, *f;
1073
1074                 if (!m->allow_fds) {
1075                         r = -ENOTSUP;
1076                         goto fail;
1077                 }
1078
1079                 align = sz = 4;
1080
1081                 z = *(int*) p;
1082                 if (z < 0) {
1083                         r = -EINVAL;
1084                         goto fail;
1085                 }
1086
1087                 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1088                 if (fd < 0) {
1089                         r = -errno;
1090                         goto fail;
1091                 }
1092
1093                 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1094                 if (!f) {
1095                         r = -ENOMEM;
1096                         goto fail;
1097                 }
1098
1099                 fdi = m->n_fds;
1100                 f[fdi] = fd;
1101                 m->fds = f;
1102                 m->free_fds = true;
1103                 break;
1104         }
1105
1106         default:
1107                 align = bus_type_get_alignment(type);
1108                 sz = bus_type_get_size(type);
1109                 break;
1110         }
1111
1112         assert(align > 0);
1113         assert(sz > 0);
1114
1115         a = message_extend_body(m, align, sz);
1116         if (!a) {
1117                 r = -ENOMEM;
1118                 goto fail;
1119         }
1120
1121         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1122                 *(uint32_t*) a = sz - 5;
1123                 memcpy((uint8_t*) a + 4, p, sz - 4);
1124
1125                 if (stored)
1126                         *stored = (const uint8_t*) a + 4;
1127
1128         } else if (type == SD_BUS_TYPE_SIGNATURE) {
1129                 *(uint8_t*) a = sz - 1;
1130                 memcpy((uint8_t*) a + 1, p, sz - 1);
1131
1132                 if (stored)
1133                         *stored = (const uint8_t*) a + 1;
1134         } else if (type == SD_BUS_TYPE_UNIX_FD) {
1135                 *(uint32_t*) a = fdi;
1136
1137                 if (stored)
1138                         *stored = a;
1139
1140                 m->n_fds ++;
1141
1142         } else {
1143                 memcpy(a, p, sz);
1144
1145                 if (stored)
1146                         *stored = a;
1147         }
1148
1149         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1150                 c->index++;
1151
1152         return 0;
1153
1154 fail:
1155         /* Truncate extended signature again */
1156         if (e)
1157                 c->signature[c->index] = 0;
1158
1159         if (fd >= 0)
1160                 close_nointr_nofail(fd);
1161
1162         return r;
1163 }
1164
1165 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1166         return message_append_basic(m, type, p, NULL);
1167 }
1168
1169 static int bus_message_open_array(
1170                 sd_bus_message *m,
1171                 struct bus_container *c,
1172                 const char *contents,
1173                 uint32_t **array_size) {
1174
1175         unsigned nindex;
1176         char *e = NULL;
1177         void *a, *b;
1178         int alignment;
1179         size_t saved;
1180
1181         assert(m);
1182         assert(c);
1183         assert(contents);
1184         assert(array_size);
1185
1186         if (!signature_is_single(contents))
1187                 return -EINVAL;
1188
1189         alignment = bus_type_get_alignment(contents[0]);
1190         if (alignment < 0)
1191                 return alignment;
1192
1193         if (c->signature && c->signature[c->index]) {
1194
1195                 /* Verify the existing signature */
1196
1197                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1198                         return -ENXIO;
1199
1200                 if (!startswith(c->signature + c->index + 1, contents))
1201                         return -ENXIO;
1202
1203                 nindex = c->index + 1 + strlen(contents);
1204         } else {
1205                 if (c->enclosing != 0)
1206                         return -ENXIO;
1207
1208                 /* Extend the existing signature */
1209
1210                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1211                 if (!e)
1212                         return -ENOMEM;
1213
1214                 nindex = e - c->signature;
1215         }
1216
1217         saved = m->header->body_size;
1218         a = message_extend_body(m, 4, 4);
1219         if (!a) {
1220                 /* Truncate extended signature again */
1221                 if (e)
1222                         c->signature[c->index] = 0;
1223
1224                 return -ENOMEM;
1225         }
1226         b = m->body;
1227
1228         if (!message_extend_body(m, alignment, 0)) {
1229                 /* Add alignment between size and first element */
1230                 if (e)
1231                         c->signature[c->index] = 0;
1232
1233                 m->header->body_size = saved;
1234                 return -ENOMEM;
1235         }
1236
1237         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1238                 c->index = nindex;
1239
1240         /* m->body might have changed so let's readjust a */
1241         a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1242         *(uint32_t*) a = 0;
1243
1244         *array_size = a;
1245         return 0;
1246 }
1247
1248 static int bus_message_open_variant(
1249                 sd_bus_message *m,
1250                 struct bus_container *c,
1251                 const char *contents) {
1252
1253         char *e = NULL;
1254         size_t l;
1255         void *a;
1256
1257         assert(m);
1258         assert(c);
1259         assert(contents);
1260
1261         if (!signature_is_single(contents))
1262                 return -EINVAL;
1263
1264         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1265                 return -EINVAL;
1266
1267         if (c->signature && c->signature[c->index]) {
1268
1269                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1270                         return -ENXIO;
1271
1272         } else {
1273                 if (c->enclosing != 0)
1274                         return -ENXIO;
1275
1276                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1277                 if (!e)
1278                         return -ENOMEM;
1279         }
1280
1281         l = strlen(contents);
1282         a = message_extend_body(m, 1, 1 + l + 1);
1283         if (!a) {
1284                 /* Truncate extended signature again */
1285                 if (e)
1286                         c->signature[c->index] = 0;
1287
1288                 return -ENOMEM;
1289         }
1290
1291         *(uint8_t*) a = l;
1292         memcpy((uint8_t*) a + 1, contents, l + 1);
1293
1294         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1295                 c->index++;
1296
1297         return 0;
1298 }
1299
1300 static int bus_message_open_struct(
1301                 sd_bus_message *m,
1302                 struct bus_container *c,
1303                 const char *contents) {
1304
1305         size_t nindex;
1306         char *e = NULL;
1307
1308         assert(m);
1309         assert(c);
1310         assert(contents);
1311
1312         if (!signature_is_valid(contents, false))
1313                 return -EINVAL;
1314
1315         if (c->signature && c->signature[c->index]) {
1316                 size_t l;
1317
1318                 l = strlen(contents);
1319
1320                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1321                     !startswith(c->signature + c->index + 1, contents) ||
1322                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1323                         return -ENXIO;
1324
1325                 nindex = c->index + 1 + l + 1;
1326         } else {
1327                 if (c->enclosing != 0)
1328                         return -ENXIO;
1329
1330                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1331                 if (!e)
1332                         return -ENOMEM;
1333
1334                 nindex = e - c->signature;
1335         }
1336
1337         /* Align contents to 8 byte boundary */
1338         if (!message_extend_body(m, 8, 0)) {
1339                 if (e)
1340                         c->signature[c->index] = 0;
1341
1342                 return -ENOMEM;
1343         }
1344
1345         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1346                 c->index = nindex;
1347
1348         return 0;
1349 }
1350
1351 static int bus_message_open_dict_entry(
1352                 sd_bus_message *m,
1353                 struct bus_container *c,
1354                 const char *contents) {
1355
1356         size_t nindex;
1357
1358         assert(m);
1359         assert(c);
1360         assert(contents);
1361
1362         if (!signature_is_pair(contents))
1363                 return -EINVAL;
1364
1365         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1366                 return -ENXIO;
1367
1368         if (c->signature && c->signature[c->index]) {
1369                 size_t l;
1370
1371                 l = strlen(contents);
1372
1373                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1374                     !startswith(c->signature + c->index + 1, contents) ||
1375                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1376                         return -ENXIO;
1377
1378                 nindex = c->index + 1 + l + 1;
1379         } else
1380                 return -ENXIO;
1381
1382         /* Align contents to 8 byte boundary */
1383         if (!message_extend_body(m, 8, 0))
1384                 return -ENOMEM;
1385
1386         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1387                 c->index = nindex;
1388
1389         return 0;
1390 }
1391
1392 int sd_bus_message_open_container(
1393                 sd_bus_message *m,
1394                 char type,
1395                 const char *contents) {
1396
1397         struct bus_container *c, *w;
1398         uint32_t *array_size = NULL;
1399         char *signature;
1400         int r;
1401
1402         if (!m)
1403                 return -EINVAL;
1404         if (m->sealed)
1405                 return -EPERM;
1406         if (!contents)
1407                 return -EINVAL;
1408
1409         /* Make sure we have space for one more container */
1410         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1411         if (!w)
1412                 return -ENOMEM;
1413         m->containers = w;
1414
1415         c = message_get_container(m);
1416
1417         signature = strdup(contents);
1418         if (!signature)
1419                 return -ENOMEM;
1420
1421         if (type == SD_BUS_TYPE_ARRAY)
1422                 r = bus_message_open_array(m, c, contents, &array_size);
1423         else if (type == SD_BUS_TYPE_VARIANT)
1424                 r = bus_message_open_variant(m, c, contents);
1425         else if (type == SD_BUS_TYPE_STRUCT)
1426                 r = bus_message_open_struct(m, c, contents);
1427         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1428                 r = bus_message_open_dict_entry(m, c, contents);
1429         else
1430                 r = -EINVAL;
1431
1432         if (r < 0) {
1433                 free(signature);
1434                 return r;
1435         }
1436
1437         /* OK, let's fill it in */
1438         w += m->n_containers++;
1439         w->enclosing = type;
1440         w->signature = signature;
1441         w->index = 0;
1442         w->array_size = array_size;
1443         w->begin = 0;
1444
1445         return 0;
1446 }
1447
1448 int sd_bus_message_close_container(sd_bus_message *m) {
1449         struct bus_container *c;
1450
1451         if (!m)
1452                 return -EINVAL;
1453         if (m->sealed)
1454                 return -EPERM;
1455         if (m->n_containers <= 0)
1456                 return -EINVAL;
1457
1458         c = message_get_container(m);
1459         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1460                 if (c->signature && c->signature[c->index] != 0)
1461                         return -EINVAL;
1462
1463         free(c->signature);
1464         m->n_containers--;
1465
1466         return 0;
1467 }
1468
1469
1470 typedef struct {
1471         const char *types;
1472         unsigned n_struct;
1473         unsigned n_array;
1474 } TypeStack;
1475
1476 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1477         assert(stack);
1478         assert(max > 0);
1479
1480         if (*i >= max)
1481                 return -EINVAL;
1482
1483         stack[*i].types = types;
1484         stack[*i].n_struct = n_struct;
1485         stack[*i].n_array = n_array;
1486         (*i)++;
1487
1488         return 0;
1489 }
1490
1491 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1492         assert(stack);
1493         assert(max > 0);
1494         assert(types);
1495         assert(n_struct);
1496         assert(n_array);
1497
1498         if (*i <= 0)
1499                 return 0;
1500
1501         (*i)--;
1502         *types = stack[*i].types;
1503         *n_struct = stack[*i].n_struct;
1504         *n_array = stack[*i].n_array;
1505
1506         return 1;
1507 }
1508
1509 int bus_message_append_ap(
1510                 sd_bus_message *m,
1511                 const char *types,
1512                 va_list ap) {
1513
1514         unsigned n_array, n_struct;
1515         TypeStack stack[BUS_CONTAINER_DEPTH];
1516         unsigned stack_ptr = 0;
1517         int r;
1518
1519         assert(m);
1520
1521         if (!types)
1522                 return 0;
1523
1524         n_array = (unsigned) -1;
1525         n_struct = strlen(types);
1526
1527         for (;;) {
1528                 const char *t;
1529
1530                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1531                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1532                         if (r < 0)
1533                                 return r;
1534                         if (r == 0)
1535                                 break;
1536
1537                         r = sd_bus_message_close_container(m);
1538                         if (r < 0)
1539                                 return r;
1540
1541                         continue;
1542                 }
1543
1544                 t = types;
1545                 if (n_array != (unsigned) -1)
1546                         n_array --;
1547                 else {
1548                         types ++;
1549                         n_struct--;
1550                 }
1551
1552                 switch (*t) {
1553
1554                 case SD_BUS_TYPE_BYTE: {
1555                         uint8_t x;
1556
1557                         x = (uint8_t) va_arg(ap, int);
1558                         r = sd_bus_message_append_basic(m, *t, &x);
1559                         break;
1560                 }
1561
1562                 case SD_BUS_TYPE_BOOLEAN:
1563                 case SD_BUS_TYPE_INT32:
1564                 case SD_BUS_TYPE_UINT32:
1565                 case SD_BUS_TYPE_UNIX_FD: {
1566                         uint32_t x;
1567
1568                         /* We assume a boolean is the same as int32_t */
1569                         assert_cc(sizeof(int32_t) == sizeof(int));
1570
1571                         x = va_arg(ap, uint32_t);
1572                         r = sd_bus_message_append_basic(m, *t, &x);
1573                         break;
1574                 }
1575
1576                 case SD_BUS_TYPE_INT16:
1577                 case SD_BUS_TYPE_UINT16: {
1578                         uint16_t x;
1579
1580                         x = (uint16_t) va_arg(ap, int);
1581                         r = sd_bus_message_append_basic(m, *t, &x);
1582                         break;
1583                 }
1584
1585                 case SD_BUS_TYPE_INT64:
1586                 case SD_BUS_TYPE_UINT64:
1587                 case SD_BUS_TYPE_DOUBLE: {
1588                         uint64_t x;
1589
1590                         x = va_arg(ap, uint64_t);
1591                         r = sd_bus_message_append_basic(m, *t, &x);
1592                         break;
1593                 }
1594
1595                 case SD_BUS_TYPE_STRING:
1596                 case SD_BUS_TYPE_OBJECT_PATH:
1597                 case SD_BUS_TYPE_SIGNATURE: {
1598                         const char *x;
1599
1600                         x = va_arg(ap, const char*);
1601                         r = sd_bus_message_append_basic(m, *t, x);
1602                         break;
1603                 }
1604
1605                 case SD_BUS_TYPE_ARRAY: {
1606                         size_t k;
1607
1608                         r = signature_element_length(t + 1, &k);
1609                         if (r < 0)
1610                                 return r;
1611
1612                         {
1613                                 char s[k + 1];
1614                                 memcpy(s, t + 1, k);
1615                                 s[k] = 0;
1616
1617                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1618                                 if (r < 0)
1619                                         return r;
1620                         }
1621
1622                         if (n_array == (unsigned) -1) {
1623                                 types += k;
1624                                 n_struct -= k;
1625                         }
1626
1627                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1628                         if (r < 0)
1629                                 return r;
1630
1631                         types = t + 1;
1632                         n_struct = k;
1633                         n_array = va_arg(ap, unsigned);
1634
1635                         break;
1636                 }
1637
1638                 case SD_BUS_TYPE_VARIANT: {
1639                         const char *s;
1640
1641                         s = va_arg(ap, const char*);
1642                         if (!s)
1643                                 return -EINVAL;
1644
1645                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1646                         if (r < 0)
1647                                 return r;
1648
1649                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1650                         if (r < 0)
1651                                 return r;
1652
1653                         types = s;
1654                         n_struct = strlen(s);
1655                         n_array = (unsigned) -1;
1656
1657                         break;
1658                 }
1659
1660                 case SD_BUS_TYPE_STRUCT_BEGIN:
1661                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1662                         size_t k;
1663
1664                         r = signature_element_length(t, &k);
1665                         if (r < 0)
1666                                 return r;
1667
1668                         {
1669                                 char s[k - 1];
1670
1671                                 memcpy(s, t + 1, k - 2);
1672                                 s[k - 2] = 0;
1673
1674                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1675                                 if (r < 0)
1676                                         return r;
1677                         }
1678
1679                         if (n_array == (unsigned) -1) {
1680                                 types += k - 1;
1681                                 n_struct -= k - 1;
1682                         }
1683
1684                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1685                         if (r < 0)
1686                                 return r;
1687
1688                         types = t + 1;
1689                         n_struct = k - 2;
1690                         n_array = (unsigned) -1;
1691
1692                         break;
1693                 }
1694
1695                 default:
1696                         r = -EINVAL;
1697                 }
1698
1699                 if (r < 0)
1700                         return r;
1701         }
1702
1703         return 0;
1704 }
1705
1706 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1707         va_list ap;
1708         int r;
1709
1710         if (!m)
1711                 return -EINVAL;
1712         if (m->sealed)
1713                 return -EPERM;
1714         if (!types)
1715                 return 0;
1716
1717         va_start(ap, types);
1718         r = bus_message_append_ap(m, types, ap);
1719         va_end(ap);
1720
1721         return r;
1722 }
1723
1724 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1725         size_t k, start, n;
1726
1727         assert(rindex);
1728         assert(align > 0);
1729
1730         start = ALIGN_TO((size_t) *rindex, align);
1731         n = start + nbytes;
1732
1733         if (n > sz)
1734                 return -EBADMSG;
1735
1736         /* Verify that padding is 0 */
1737         for (k = *rindex; k < start; k++)
1738                 if (((const uint8_t*) p)[k] != 0)
1739                         return -EBADMSG;
1740
1741         if (r)
1742                 *r = (uint8_t*) p + start;
1743
1744         *rindex = n;
1745
1746         return 1;
1747 }
1748
1749 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1750         struct bus_container *c;
1751
1752         assert(m);
1753
1754         c = message_get_container(m);
1755         if (!c->array_size)
1756                 return false;
1757
1758         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1759 }
1760
1761 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1762         assert(m);
1763         assert(rindex);
1764         assert(align > 0);
1765
1766         if (message_end_of_array(m, *rindex))
1767                 return 0;
1768
1769         return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1770 }
1771
1772 static bool validate_nul(const char *s, size_t l) {
1773
1774         /* Check for NUL chars in the string */
1775         if (memchr(s, 0, l))
1776                 return false;
1777
1778         /* Check for NUL termination */
1779         if (s[l] != 0)
1780                 return false;
1781
1782         return true;
1783 }
1784
1785 static bool validate_string(const char *s, size_t l) {
1786
1787         if (!validate_nul(s, l))
1788                 return false;
1789
1790         /* Check if valid UTF8 */
1791         if (!utf8_is_valid(s))
1792                 return false;
1793
1794         return true;
1795 }
1796
1797 static bool validate_signature(const char *s, size_t l) {
1798
1799         if (!validate_nul(s, l))
1800                 return false;
1801
1802         /* Check if valid signature */
1803         if (!signature_is_valid(s, true))
1804                 return false;
1805
1806         return true;
1807 }
1808
1809 static bool validate_object_path(const char *s, size_t l) {
1810
1811         if (!validate_nul(s, l))
1812                 return false;
1813
1814         if (!object_path_is_valid(s))
1815                 return false;
1816
1817         return true;
1818 }
1819
1820 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1821         struct bus_container *c;
1822         int r;
1823         void *q;
1824
1825         if (!m)
1826                 return -EINVAL;
1827         if (!m->sealed)
1828                 return -EPERM;
1829         if (!bus_type_is_basic(type))
1830                 return -EINVAL;
1831         if (!p)
1832                 return -EINVAL;
1833
1834         c = message_get_container(m);
1835
1836         if (!c->signature || c->signature[c->index] == 0)
1837                 return 0;
1838
1839         if (c->signature[c->index] != type)
1840                 return -ENXIO;
1841
1842         switch (type) {
1843
1844         case SD_BUS_TYPE_STRING:
1845         case SD_BUS_TYPE_OBJECT_PATH: {
1846                 uint32_t l;
1847                 size_t rindex;
1848
1849                 rindex = m->rindex;
1850                 r = message_peek_body(m, &rindex, 4, 4, &q);
1851                 if (r <= 0)
1852                         return r;
1853
1854                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1855                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1856                 if (r < 0)
1857                         return r;
1858                 if (r == 0)
1859                         return -EBADMSG;
1860
1861                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1862                         if (!validate_object_path(q, l))
1863                                 return -EBADMSG;
1864                 } else {
1865                         if (!validate_string(q, l))
1866                                 return -EBADMSG;
1867                 }
1868
1869                 m->rindex = rindex;
1870                 *(const char**) p = q;
1871                 break;
1872         }
1873
1874         case SD_BUS_TYPE_SIGNATURE: {
1875                 uint8_t l;
1876                 size_t rindex;
1877
1878                 rindex = m->rindex;
1879                 r = message_peek_body(m, &rindex, 1, 1, &q);
1880                 if (r <= 0)
1881                         return r;
1882
1883                 l = *(uint8_t*) q;
1884                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1885                 if (r < 0)
1886                         return r;
1887                 if (r == 0)
1888                         return -EBADMSG;
1889
1890                 if (!validate_signature(q, l))
1891                         return -EBADMSG;
1892
1893                 m->rindex = rindex;
1894                 *(const char**) p = q;
1895                 break;
1896         }
1897
1898         default: {
1899                 ssize_t sz, align;
1900                 size_t rindex;
1901
1902                 align = bus_type_get_alignment(type);
1903                 sz = bus_type_get_size(type);
1904                 assert(align > 0 && sz > 0);
1905
1906                 rindex = m->rindex;
1907                 r = message_peek_body(m, &rindex, align, sz, &q);
1908                 if (r <= 0)
1909                         return r;
1910
1911                 switch (type) {
1912
1913                 case SD_BUS_TYPE_BYTE:
1914                         *(uint8_t*) p = *(uint8_t*) q;
1915                         break;
1916
1917                 case SD_BUS_TYPE_BOOLEAN:
1918                         *(int*) p = !!*(uint32_t*) q;
1919                         break;
1920
1921                 case SD_BUS_TYPE_INT16:
1922                 case SD_BUS_TYPE_UINT16:
1923                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1924                         break;
1925
1926                 case SD_BUS_TYPE_INT32:
1927                 case SD_BUS_TYPE_UINT32:
1928                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1929                         break;
1930
1931                 case SD_BUS_TYPE_INT64:
1932                 case SD_BUS_TYPE_UINT64:
1933                 case SD_BUS_TYPE_DOUBLE:
1934                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1935                         break;
1936
1937                 case SD_BUS_TYPE_UNIX_FD: {
1938                         uint32_t j;
1939
1940                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1941                         if (j >= m->n_fds)
1942                                 return -EBADMSG;
1943
1944                         *(int*) p = m->fds[j];
1945                         break;
1946                 }
1947
1948                 default:
1949                         assert_not_reached("Unknown basic type...");
1950                 }
1951
1952                         m->rindex = rindex;
1953
1954                 break;
1955         }
1956         }
1957
1958         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1959                 c->index++;
1960
1961         return 1;
1962 }
1963
1964 static int bus_message_enter_array(
1965                 sd_bus_message *m,
1966                 struct bus_container *c,
1967                 const char *contents,
1968                 uint32_t **array_size) {
1969
1970         size_t rindex;
1971         void *q;
1972         int r, alignment;
1973
1974         assert(m);
1975         assert(c);
1976         assert(contents);
1977         assert(array_size);
1978
1979         if (!signature_is_single(contents))
1980                 return -EINVAL;
1981
1982         alignment = bus_type_get_alignment(contents[0]);
1983         if (alignment < 0)
1984                 return alignment;
1985
1986         if (!c->signature || c->signature[c->index] == 0)
1987                 return 0;
1988
1989         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1990                 return -ENXIO;
1991
1992         if (!startswith(c->signature + c->index + 1, contents))
1993                 return -ENXIO;
1994
1995         rindex = m->rindex;
1996         r = message_peek_body(m, &rindex, 4, 4, &q);
1997         if (r <= 0)
1998                 return r;
1999
2000         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2001                 return -EBADMSG;
2002
2003         r = message_peek_body(m, &rindex, alignment, 0, NULL);
2004         if (r < 0)
2005                 return r;
2006         if (r == 0)
2007                 return -EBADMSG;
2008
2009         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2010                 c->index += 1 + strlen(contents);
2011
2012         m->rindex = rindex;
2013
2014         *array_size = (uint32_t*) q;
2015
2016         return 1;
2017 }
2018
2019 static int bus_message_enter_variant(
2020                 sd_bus_message *m,
2021                 struct bus_container *c,
2022                 const char *contents) {
2023
2024         size_t rindex;
2025         uint8_t l;
2026         void *q;
2027         int r;
2028
2029         assert(m);
2030         assert(c);
2031         assert(contents);
2032
2033         if (!signature_is_single(contents))
2034                 return -EINVAL;
2035
2036         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2037                 return -EINVAL;
2038
2039         if (!c->signature || c->signature[c->index] == 0)
2040                 return 0;
2041
2042         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2043                 return -ENXIO;
2044
2045         rindex = m->rindex;
2046         r = message_peek_body(m, &rindex, 1, 1, &q);
2047         if (r <= 0)
2048                 return r;
2049
2050         l = *(uint8_t*) q;
2051         r = message_peek_body(m, &rindex, 1, l+1, &q);
2052         if (r < 0)
2053                 return r;
2054         if (r == 0)
2055                 return -EBADMSG;
2056
2057         if (!validate_signature(q, l))
2058                 return -EBADMSG;
2059
2060         if (!streq(q, contents))
2061                 return -ENXIO;
2062
2063         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2064                 c->index++;
2065
2066         m->rindex = rindex;
2067
2068         return 1;
2069 }
2070
2071 static int bus_message_enter_struct(
2072                 sd_bus_message *m,
2073                 struct bus_container *c,
2074                 const char *contents) {
2075
2076         size_t l;
2077         int r;
2078
2079         assert(m);
2080         assert(c);
2081         assert(contents);
2082
2083         if (!signature_is_valid(contents, false))
2084                 return -EINVAL;
2085
2086         if (!c->signature || c->signature[c->index] == 0)
2087                 return 0;
2088
2089         l = strlen(contents);
2090
2091         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2092             !startswith(c->signature + c->index + 1, contents) ||
2093             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2094                 return -ENXIO;
2095
2096         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2097         if (r <= 0)
2098                 return r;
2099
2100         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2101                 c->index += 1 + l + 1;
2102
2103         return 1;
2104 }
2105
2106 static int bus_message_enter_dict_entry(
2107                 sd_bus_message *m,
2108                 struct bus_container *c,
2109                 const char *contents) {
2110
2111         size_t l;
2112         int r;
2113
2114         assert(m);
2115         assert(c);
2116         assert(contents);
2117
2118         if (!signature_is_pair(contents))
2119                 return -EINVAL;
2120
2121         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2122                 return -ENXIO;
2123
2124         if (!c->signature || c->signature[c->index] == 0)
2125                 return 0;
2126
2127         l = strlen(contents);
2128
2129         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2130             !startswith(c->signature + c->index + 1, contents) ||
2131             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2132                 return -ENXIO;
2133
2134         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2135         if (r <= 0)
2136                 return r;
2137
2138         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2139                 c->index += 1 + l + 1;
2140
2141         return 1;
2142 }
2143
2144 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2145         struct bus_container *c, *w;
2146         uint32_t *array_size = NULL;
2147         char *signature;
2148         int r;
2149
2150         if (!m)
2151                 return -EINVAL;
2152         if (!m->sealed)
2153                 return -EPERM;
2154         if (!contents)
2155                 return -EINVAL;
2156
2157         /*
2158          * We enforce a global limit on container depth, that is much
2159          * higher than the 32 structs and 32 arrays the specification
2160          * mandates. This is simpler to implement for us, and we need
2161          * this only to ensure our container array doesn't grow
2162          * without bounds. We are happy to return any data from a
2163          * message as long as the data itself is valid, even if the
2164          * overall message might be not.
2165          *
2166          * Note that the message signature is validated when
2167          * parsing the headers, and that validation does check the
2168          * 32/32 limit.
2169          *
2170          * Note that the specification defines no limits on the depth
2171          * of stacked variants, but we do.
2172          */
2173         if (m->n_containers >= BUS_CONTAINER_DEPTH)
2174                 return -EBADMSG;
2175
2176         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2177         if (!w)
2178                 return -ENOMEM;
2179         m->containers = w;
2180
2181         c = message_get_container(m);
2182
2183         if (!c->signature || c->signature[c->index] == 0)
2184                 return 0;
2185
2186         signature = strdup(contents);
2187         if (!signature)
2188                 return -ENOMEM;
2189
2190         if (type == SD_BUS_TYPE_ARRAY)
2191                 r = bus_message_enter_array(m, c, contents, &array_size);
2192         else if (type == SD_BUS_TYPE_VARIANT)
2193                 r = bus_message_enter_variant(m, c, contents);
2194         else if (type == SD_BUS_TYPE_STRUCT)
2195                 r = bus_message_enter_struct(m, c, contents);
2196         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2197                 r = bus_message_enter_dict_entry(m, c, contents);
2198         else
2199                 r = -EINVAL;
2200
2201         if (r <= 0) {
2202                 free(signature);
2203                 return r;
2204         }
2205
2206         /* OK, let's fill it in */
2207         w += m->n_containers++;
2208         w->enclosing = type;
2209         w->signature = signature;
2210         w->index = 0;
2211         w->array_size = array_size;
2212         w->begin = m->rindex;
2213
2214         return 1;
2215 }
2216
2217 int sd_bus_message_exit_container(sd_bus_message *m) {
2218         struct bus_container *c;
2219
2220         if (!m)
2221                 return -EINVAL;
2222         if (!m->sealed)
2223                 return -EPERM;
2224         if (m->n_containers <= 0)
2225                 return -EINVAL;
2226
2227         c = message_get_container(m);
2228         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2229                 uint32_t l;
2230
2231                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2232                 if (c->begin + l != m->rindex)
2233                         return -EBUSY;
2234
2235         } else {
2236                 if (c->signature && c->signature[c->index] != 0)
2237                         return -EINVAL;
2238         }
2239
2240         free(c->signature);
2241         m->n_containers--;
2242
2243         return 1;
2244 }
2245
2246 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2247         struct bus_container *c;
2248         int r;
2249
2250         if (!m)
2251                 return -EINVAL;
2252         if (!m->sealed)
2253                 return -EPERM;
2254
2255         c = message_get_container(m);
2256
2257         if (!c->signature || c->signature[c->index] == 0)
2258                 goto eof;
2259
2260         if (message_end_of_array(m, m->rindex))
2261                 goto eof;
2262
2263         if (bus_type_is_basic(c->signature[c->index])) {
2264                 if (contents)
2265                         *contents = NULL;
2266                 if (type)
2267                         *type = c->signature[c->index];
2268                 return 1;
2269         }
2270
2271         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2272
2273                 if (contents) {
2274                         size_t l;
2275                         char *sig;
2276
2277                         r = signature_element_length(c->signature+c->index+1, &l);
2278                         if (r < 0)
2279                                 return r;
2280
2281                         assert(l >= 1);
2282
2283                         sig = strndup(c->signature + c->index + 1, l);
2284                         if (!sig)
2285                                 return -ENOMEM;
2286
2287                         free(m->peeked_signature);
2288                         m->peeked_signature = sig;
2289
2290                         *contents = sig;
2291                 }
2292
2293                 if (type)
2294                         *type = SD_BUS_TYPE_ARRAY;
2295
2296                 return 1;
2297         }
2298
2299         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2300             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2301
2302                 if (contents) {
2303                         size_t l;
2304                         char *sig;
2305
2306                         r = signature_element_length(c->signature+c->index, &l);
2307                         if (r < 0)
2308                                 return r;
2309
2310                         assert(l >= 2);
2311                         sig = strndup(c->signature + c->index + 1, l - 2);
2312                         if (!sig)
2313                                 return -ENOMEM;
2314
2315                         free(m->peeked_signature);
2316                         m->peeked_signature = sig;
2317
2318                         *contents = sig;
2319                 }
2320
2321                 if (type)
2322                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2323
2324                 return 1;
2325         }
2326
2327         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2328                 if (contents) {
2329                         size_t rindex, l;
2330                         void *q;
2331
2332                         rindex = m->rindex;
2333                         r = message_peek_body(m, &rindex, 1, 1, &q);
2334                         if (r < 0)
2335                                 return r;
2336                         if (r == 0)
2337                                 goto eof;
2338
2339                         l = *(uint8_t*) q;
2340                         r = message_peek_body(m, &rindex, 1, l+1, &q);
2341                         if (r < 0)
2342                                 return r;
2343                         if (r == 0)
2344                                 return -EBADMSG;
2345
2346                         if (!validate_signature(q, l))
2347                                 return -EBADMSG;
2348
2349                         *contents = q;
2350                 }
2351
2352                 if (type)
2353                         *type = SD_BUS_TYPE_VARIANT;
2354
2355                 return 1;
2356         }
2357
2358         return -EINVAL;
2359
2360 eof:
2361         if (type)
2362                 *type = c->enclosing;
2363         if (contents)
2364                 *contents = NULL;
2365         return 0;
2366 }
2367
2368 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2369         struct bus_container *c;
2370
2371         if (!m)
2372                 return -EINVAL;
2373         if (!m->sealed)
2374                 return -EPERM;
2375
2376         if (complete) {
2377                 reset_containers(m);
2378                 m->rindex = 0;
2379                 m->root_container.index = 0;
2380
2381                 c = message_get_container(m);
2382         } else {
2383                 c = message_get_container(m);
2384
2385                 c->index = 0;
2386                 m->rindex = c->begin;
2387         }
2388
2389         return !isempty(c->signature);
2390 }
2391 static int message_read_ap(
2392                 sd_bus_message *m,
2393                 const char *types,
2394                 va_list ap) {
2395
2396         unsigned n_array, n_struct;
2397         TypeStack stack[BUS_CONTAINER_DEPTH];
2398         unsigned stack_ptr = 0;
2399         int r;
2400
2401         assert(m);
2402
2403         if (!types)
2404                 return 0;
2405
2406         /* Ideally, we'd just call ourselves recursively on every
2407          * complex type. However, the state of a va_list that is
2408          * passed to a function is undefined after that function
2409          * returns. This means we need to docode the va_list linearly
2410          * in a single stackframe. We hence implement our own
2411          * home-grown stack in an array. */
2412
2413         n_array = (unsigned) -1;
2414         n_struct = strlen(types);
2415
2416         for (;;) {
2417                 const char *t;
2418
2419                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2420                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2421                         if (r < 0)
2422                                 return r;
2423                         if (r == 0)
2424                                 break;
2425
2426                         r = sd_bus_message_exit_container(m);
2427                         if (r < 0)
2428                                 return r;
2429
2430                         continue;
2431                 }
2432
2433                 t = types;
2434                 if (n_array != (unsigned) -1)
2435                         n_array --;
2436                 else {
2437                         types ++;
2438                         n_struct--;
2439                 }
2440
2441                 switch (*t) {
2442
2443                 case SD_BUS_TYPE_BYTE:
2444                 case SD_BUS_TYPE_BOOLEAN:
2445                 case SD_BUS_TYPE_INT16:
2446                 case SD_BUS_TYPE_UINT16:
2447                 case SD_BUS_TYPE_INT32:
2448                 case SD_BUS_TYPE_UINT32:
2449                 case SD_BUS_TYPE_INT64:
2450                 case SD_BUS_TYPE_UINT64:
2451                 case SD_BUS_TYPE_DOUBLE:
2452                 case SD_BUS_TYPE_STRING:
2453                 case SD_BUS_TYPE_OBJECT_PATH:
2454                 case SD_BUS_TYPE_SIGNATURE:
2455                 case SD_BUS_TYPE_UNIX_FD: {
2456                         void *p;
2457
2458                         p = va_arg(ap, void*);
2459                         r = sd_bus_message_read_basic(m, *t, p);
2460                         if (r < 0)
2461                                 return r;
2462                         if (r == 0)
2463                                 return -ENXIO;
2464
2465                         break;
2466                 }
2467
2468                 case SD_BUS_TYPE_ARRAY: {
2469                         size_t k;
2470
2471                         r = signature_element_length(t + 1, &k);
2472                         if (r < 0)
2473                                 return r;
2474
2475                         {
2476                                 char s[k + 1];
2477                                 memcpy(s, t + 1, k);
2478                                 s[k] = 0;
2479
2480                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2481                                 if (r < 0)
2482                                         return r;
2483                                 if (r == 0)
2484                                         return -ENXIO;
2485                         }
2486
2487                         if (n_array == (unsigned) -1) {
2488                                 types += k;
2489                                 n_struct -= k;
2490                         }
2491
2492                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2493                         if (r < 0)
2494                                 return r;
2495
2496                         types = t + 1;
2497                         n_struct = k;
2498                         n_array = va_arg(ap, unsigned);
2499
2500                         break;
2501                 }
2502
2503                 case SD_BUS_TYPE_VARIANT: {
2504                         const char *s;
2505
2506                         s = va_arg(ap, const char *);
2507                         if (!s)
2508                                 return -EINVAL;
2509
2510                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2511                         if (r < 0)
2512                                 return r;
2513                         if (r == 0)
2514                                 return -ENXIO;
2515
2516                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2517                         if (r < 0)
2518                                 return r;
2519
2520                         types = s;
2521                         n_struct = strlen(s);
2522                         n_array = (unsigned) -1;
2523
2524                         break;
2525                 }
2526
2527                 case SD_BUS_TYPE_STRUCT_BEGIN:
2528                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2529                         size_t k;
2530
2531                         r = signature_element_length(t, &k);
2532                         if (r < 0)
2533                                 return r;
2534
2535                         {
2536                                 char s[k - 1];
2537                                 memcpy(s, t + 1, k - 2);
2538                                 s[k - 2] = 0;
2539
2540                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2541                                 if (r < 0)
2542                                         return r;
2543                                 if (r == 0)
2544                                         return -ENXIO;
2545                         }
2546
2547                         if (n_array == (unsigned) -1) {
2548                                 types += k - 1;
2549                                 n_struct -= k - 1;
2550                         }
2551
2552                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2553                         if (r < 0)
2554                                 return r;
2555
2556                         types = t + 1;
2557                         n_struct = k - 2;
2558                         n_array = (unsigned) -1;
2559
2560                         break;
2561                 }
2562
2563                 default:
2564                         return -EINVAL;
2565                 }
2566         }
2567
2568         return 1;
2569 }
2570
2571 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2572         va_list ap;
2573         int r;
2574
2575         if (!m)
2576                 return -EINVAL;
2577         if (!m->sealed)
2578                 return -EPERM;
2579         if (!types)
2580                 return -EINVAL;
2581
2582         va_start(ap, types);
2583         r = message_read_ap(m, types, ap);
2584         va_end(ap);
2585
2586         return r;
2587 }
2588
2589 static int message_peek_fields(
2590                 sd_bus_message *m,
2591                 size_t *rindex,
2592                 size_t align,
2593                 size_t nbytes,
2594                 void **ret) {
2595
2596         assert(m);
2597         assert(rindex);
2598         assert(align > 0);
2599
2600         return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2601 }
2602
2603 static int message_peek_field_uint32(
2604                 sd_bus_message *m,
2605                 size_t *ri,
2606                 uint32_t *ret) {
2607
2608         int r;
2609         void *q;
2610
2611         assert(m);
2612         assert(ri);
2613
2614         r = message_peek_fields(m, ri, 4, 4, &q);
2615         if (r < 0)
2616                 return r;
2617
2618         if (ret)
2619                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2620
2621         return 0;
2622 }
2623
2624 static int message_peek_field_string(
2625                 sd_bus_message *m,
2626                 bool (*validate)(const char *p),
2627                 size_t *ri,
2628                 const char **ret) {
2629
2630         uint32_t l;
2631         int r;
2632         void *q;
2633
2634         assert(m);
2635         assert(ri);
2636
2637         r = message_peek_field_uint32(m, ri, &l);
2638         if (r < 0)
2639                 return r;
2640
2641         r = message_peek_fields(m, ri, 1, l+1, &q);
2642         if (r < 0)
2643                 return r;
2644
2645         if (validate) {
2646                 if (!validate_nul(q, l))
2647                         return -EBADMSG;
2648
2649                 if (!validate(q))
2650                         return -EBADMSG;
2651         } else {
2652                 if (!validate_string(q, l))
2653                         return -EBADMSG;
2654         }
2655
2656         if (ret)
2657                 *ret = q;
2658
2659         return 0;
2660 }
2661
2662 static int message_peek_field_signature(
2663                 sd_bus_message *m,
2664                 size_t *ri,
2665                 const char **ret) {
2666
2667         size_t l;
2668         int r;
2669         void *q;
2670
2671         assert(m);
2672         assert(ri);
2673
2674         r = message_peek_fields(m, ri, 1, 1, &q);
2675         if (r < 0)
2676                 return r;
2677
2678         l = *(uint8_t*) q;
2679         r = message_peek_fields(m, ri, 1, l+1, &q);
2680         if (r < 0)
2681                 return r;
2682
2683         if (!validate_signature(q, l))
2684                 return -EBADMSG;
2685
2686         if (ret)
2687                 *ret = q;
2688
2689         return 0;
2690 }
2691
2692 static int message_skip_fields(
2693                 sd_bus_message *m,
2694                 size_t *ri,
2695                 uint32_t array_size,
2696                 const char **signature) {
2697
2698         size_t original_index;
2699         int r;
2700
2701         assert(m);
2702         assert(ri);
2703         assert(signature);
2704
2705         original_index = *ri;
2706
2707         for (;;) {
2708                 char t;
2709                 size_t l;
2710
2711                 if (array_size != (uint32_t) -1 &&
2712                     array_size <= *ri - original_index)
2713                         return 0;
2714
2715                 t = **signature;
2716                 if (!t)
2717                         return 0;
2718
2719                 if (t == SD_BUS_TYPE_STRING) {
2720
2721                         r = message_peek_field_string(m, NULL, ri, NULL);
2722                         if (r < 0)
2723                                 return r;
2724
2725                         (*signature)++;
2726
2727                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2728
2729                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2730                         if (r < 0)
2731                                 return r;
2732
2733                         (*signature)++;
2734
2735                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2736
2737                         r = message_peek_field_signature(m, ri, NULL);
2738                         if (r < 0)
2739                                 return r;
2740
2741                         (*signature)++;
2742
2743                 } else if (bus_type_is_basic(t)) {
2744                         ssize_t align, k;
2745
2746                         align = bus_type_get_alignment(t);
2747                         k = bus_type_get_size(t);
2748                         assert(align > 0 && k > 0);
2749
2750                         r = message_peek_fields(m, ri, align, k, NULL);
2751                         if (r < 0)
2752                                 return r;
2753
2754                         (*signature)++;
2755
2756                 } else if (t == SD_BUS_TYPE_ARRAY) {
2757
2758                         r = signature_element_length(*signature+1, &l);
2759                         if (r < 0)
2760                                 return r;
2761
2762                         assert(l >= 1);
2763                         {
2764                                 char sig[l-1], *s;
2765                                 uint32_t nas;
2766                                 int alignment;
2767
2768                                 strncpy(sig, *signature + 1, l-1);
2769                                 s = sig;
2770
2771                                 alignment = bus_type_get_alignment(sig[0]);
2772                                 if (alignment < 0)
2773                                         return alignment;
2774
2775                                 r = message_peek_field_uint32(m, ri, &nas);
2776                                 if (r < 0)
2777                                         return r;
2778                                 if (nas > BUS_ARRAY_MAX_SIZE)
2779                                         return -EBADMSG;
2780
2781                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
2782                                 if (r < 0)
2783                                         return r;
2784
2785                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
2786                                 if (r < 0)
2787                                         return r;
2788                         }
2789
2790                         (*signature) += 1 + l;
2791
2792                 } else if (t == SD_BUS_TYPE_VARIANT) {
2793                         const char *s;
2794
2795                         r = message_peek_field_signature(m, ri, &s);
2796                         if (r < 0)
2797                                 return r;
2798
2799                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2800                         if (r < 0)
2801                                 return r;
2802
2803                         (*signature)++;
2804
2805                 } else if (t == SD_BUS_TYPE_STRUCT ||
2806                            t == SD_BUS_TYPE_DICT_ENTRY) {
2807
2808                         r = signature_element_length(*signature, &l);
2809                         if (r < 0)
2810                                 return r;
2811
2812                         assert(l >= 2);
2813                         {
2814                                 char sig[l-1], *s;
2815                                 strncpy(sig, *signature + 1, l-1);
2816                                 s = sig;
2817
2818                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2819                                 if (r < 0)
2820                                         return r;
2821                         }
2822
2823                         *signature += l;
2824                 } else
2825                         return -EINVAL;
2826         }
2827 }
2828
2829 int bus_message_parse_fields(sd_bus_message *m) {
2830         size_t ri;
2831         int r;
2832         uint32_t unix_fds = 0;
2833
2834         assert(m);
2835
2836         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2837                 const char *signature;
2838                 uint8_t *header;
2839
2840                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2841                 if (r < 0)
2842                         return r;
2843
2844                 r = message_peek_field_signature(m, &ri, &signature);
2845                 if (r < 0)
2846                         return r;
2847
2848                 switch (*header) {
2849                 case _SD_BUS_MESSAGE_HEADER_INVALID:
2850                         return -EBADMSG;
2851
2852                 case SD_BUS_MESSAGE_HEADER_PATH:
2853
2854                         if (m->path)
2855                                 return -EBADMSG;
2856
2857                         if (!streq(signature, "o"))
2858                                 return -EBADMSG;
2859
2860                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2861                         break;
2862
2863                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2864
2865                         if (m->interface)
2866                                 return -EBADMSG;
2867
2868                         if (!streq(signature, "s"))
2869                                 return -EBADMSG;
2870
2871                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2872                         break;
2873
2874                 case SD_BUS_MESSAGE_HEADER_MEMBER:
2875
2876                         if (m->member)
2877                                 return -EBADMSG;
2878
2879                         if (!streq(signature, "s"))
2880                                 return -EBADMSG;
2881
2882                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2883                         break;
2884
2885                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2886
2887                         if (m->error.name)
2888                                 return -EBADMSG;
2889
2890                         if (!streq(signature, "s"))
2891                                 return -EBADMSG;
2892
2893                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2894                         break;
2895
2896                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2897
2898                         if (m->destination)
2899                                 return -EBADMSG;
2900
2901                         if (!streq(signature, "s"))
2902                                 return -EBADMSG;
2903
2904                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2905                         break;
2906
2907                 case SD_BUS_MESSAGE_HEADER_SENDER:
2908
2909                         if (m->sender)
2910                                 return -EBADMSG;
2911
2912                         if (!streq(signature, "s"))
2913                                 return -EBADMSG;
2914
2915                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2916                         break;
2917
2918
2919                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2920                         const char *s;
2921                         char *c;
2922
2923                         if (m->root_container.signature)
2924                                 return -EBADMSG;
2925
2926                         if (!streq(signature, "g"))
2927                                 return -EBADMSG;
2928
2929                         r = message_peek_field_signature(m, &ri, &s);
2930                         if (r < 0)
2931                                 return r;
2932
2933                         c = strdup(s);
2934                         if (!c)
2935                                 return -ENOMEM;
2936
2937                         free(m->root_container.signature);
2938                         m->root_container.signature = c;
2939                         break;
2940                 }
2941
2942                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2943                         if (m->reply_serial != 0)
2944                                 return -EBADMSG;
2945
2946                         if (!streq(signature, "u"))
2947                                 return -EBADMSG;
2948
2949                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2950                         if (r < 0)
2951                                 return r;
2952
2953                         if (m->reply_serial == 0)
2954                                 return -EBADMSG;
2955
2956                         break;
2957
2958                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2959                         if (unix_fds != 0)
2960                                 return -EBADMSG;
2961
2962                         if (!streq(signature, "u"))
2963                                 return -EBADMSG;
2964
2965                         r = message_peek_field_uint32(m, &ri, &unix_fds);
2966                         if (r < 0)
2967                                 return -EBADMSG;
2968
2969                         if (unix_fds == 0)
2970                                 return -EBADMSG;
2971
2972                         break;
2973
2974                 default:
2975                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2976                 }
2977
2978                 if (r < 0)
2979                         return r;
2980         }
2981
2982         if (m->n_fds != unix_fds)
2983                 return -EBADMSG;
2984
2985         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2986                 return -EBADMSG;
2987
2988         switch (m->header->type) {
2989
2990         case SD_BUS_MESSAGE_TYPE_SIGNAL:
2991                 if (!m->path || !m->interface || !m->member)
2992                         return -EBADMSG;
2993                 break;
2994
2995         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2996
2997                 if (!m->path || !m->member)
2998                         return -EBADMSG;
2999
3000                 break;
3001
3002         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3003
3004                 if (m->reply_serial == 0)
3005                         return -EBADMSG;
3006                 break;
3007
3008         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3009
3010                 if (m->reply_serial == 0 || !m->error.name)
3011                         return -EBADMSG;
3012                 break;
3013         }
3014
3015         /* Try to read the error message, but if we can't it's a non-issue */
3016         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3017                 sd_bus_message_read(m, "s", &m->error.message);
3018
3019         return 0;
3020 }
3021
3022 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3023         int r;
3024         size_t l, a;
3025
3026         assert(m);
3027
3028         if (m->sealed)
3029                 return -EPERM;
3030
3031         if (m->n_containers > 0)
3032                 return -EBADMSG;
3033
3034         /* If there's a non-trivial signature set, then add it in here */
3035         if (!isempty(m->root_container.signature)) {
3036                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3037                 if (r < 0)
3038                         return r;
3039         }
3040
3041         if (m->n_fds > 0) {
3042                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3043                 if (r < 0)
3044                         return r;
3045         }
3046
3047         l = BUS_MESSAGE_FIELDS_SIZE(m);
3048         a = ALIGN8(l) - l;
3049
3050         if (a > 0) {
3051                 /* Add padding at the end, since we know the body
3052                  * needs to start at an 8 byte alignment. */
3053                 void *p;
3054
3055                 p = message_extend_fields(m, 1, a);
3056                 if (!p)
3057                         return -ENOMEM;
3058
3059                 memset(p, 0, a);
3060                 m->header->fields_size -= a;
3061         }
3062
3063         m->header->serial = serial;
3064         m->sealed = true;
3065
3066         return 0;
3067 }
3068
3069 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3070         if (!m)
3071                 return -EINVAL;
3072         if (!destination)
3073                 return -EINVAL;
3074         if (m->sealed)
3075                 return -EPERM;
3076         if (m->destination)
3077                 return -EEXIST;
3078
3079         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3080 }
3081
3082 int bus_message_dump(sd_bus_message *m) {
3083         const char *u = NULL, *uu = NULL, *s = NULL;
3084         char **cmdline = NULL;
3085         unsigned level = 1;
3086         int r;
3087         uid_t owner;
3088
3089         assert(m);
3090
3091         printf("Message %p\n"
3092                "\tn_ref=%u\n"
3093                "\tendian=%c\n"
3094                "\ttype=%i\n"
3095                "\tflags=%u\n"
3096                "\tversion=%u\n"
3097                "\tserial=%u\n"
3098                "\tfields_size=%u\n"
3099                "\tbody_size=%u\n"
3100                "\tpath=%s\n"
3101                "\tinterface=%s\n"
3102                "\tmember=%s\n"
3103                "\tdestination=%s\n"
3104                "\tsender=%s\n"
3105                "\tsignature=%s\n"
3106                "\treply_serial=%u\n"
3107                "\terror.name=%s\n"
3108                "\terror.message=%s\n"
3109                "\tsealed=%s\n",
3110                m,
3111                m->n_ref,
3112                m->header->endian,
3113                m->header->type,
3114                m->header->flags,
3115                m->header->version,
3116                BUS_MESSAGE_SERIAL(m),
3117                BUS_MESSAGE_FIELDS_SIZE(m),
3118                BUS_MESSAGE_BODY_SIZE(m),
3119                strna(m->path),
3120                strna(m->interface),
3121                strna(m->member),
3122                strna(m->destination),
3123                strna(m->sender),
3124                strna(m->root_container.signature),
3125                m->reply_serial,
3126                strna(m->error.name),
3127                strna(m->error.message),
3128                yes_no(m->sealed));
3129
3130         if (m->pid != 0)
3131                 printf("\tpid=%lu\n", (unsigned long) m->pid);
3132         if (m->tid != 0)
3133                 printf("\ttid=%lu\n", (unsigned long) m->tid);
3134         if (m->uid_valid)
3135                 printf("\tuid=%lu\n", (unsigned long) m->uid);
3136         if (m->gid_valid)
3137                 printf("\tgid=%lu\n", (unsigned long) m->gid);
3138         if (m->pid_starttime != 0)
3139                 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3140         if (m->monotonic != 0)
3141                 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3142         if (m->realtime != 0)
3143                 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3144         if (m->exe)
3145                 printf("\texe=[%s]\n", m->exe);
3146         if (m->comm)
3147                 printf("\tcomm=[%s]\n", m->comm);
3148         if (m->tid_comm)
3149                 printf("\ttid_comm=[%s]\n", m->tid_comm);
3150         if (m->label)
3151                 printf("\tlabel=[%s]\n", m->label);
3152         if (m->cgroup)
3153                 printf("\tcgroup=[%s]\n", m->cgroup);
3154
3155         sd_bus_message_get_unit(m, &u);
3156         if (u)
3157                 printf("\tunit=[%s]\n", u);
3158         sd_bus_message_get_user_unit(m, &uu);
3159         if (uu)
3160                 printf("\tuser_unit=[%s]\n", uu);
3161         sd_bus_message_get_session(m, &s);
3162         if (s)
3163                 printf("\tsession=[%s]\n", s);
3164         if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3165                 printf("\towner_uid=%lu\n", (unsigned long) owner);
3166
3167         if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3168                 char **c;
3169
3170                 fputs("\tcmdline=[", stdout);
3171                 STRV_FOREACH(c, cmdline) {
3172                         if (c != cmdline)
3173                                 putchar(' ');
3174
3175                         fputs(*c, stdout);
3176                 }
3177
3178                 fputs("]\n", stdout);
3179         }
3180
3181         r = sd_bus_message_rewind(m, true);
3182         if (r < 0) {
3183                 log_error("Failed to rewind: %s", strerror(-r));
3184                 return r;
3185         }
3186
3187         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3188
3189         for(;;) {
3190                 _cleanup_free_ char *prefix = NULL;
3191                 const char *contents = NULL;
3192                 char type;
3193                 union {
3194                         uint8_t u8;
3195                         uint16_t u16;
3196                         int16_t s16;
3197                         uint32_t u32;
3198                         int32_t s32;
3199                         uint64_t u64;
3200                         int64_t s64;
3201                         double d64;
3202                         const char *string;
3203                         int i;
3204                 } basic;
3205
3206                 r = sd_bus_message_peek_type(m, &type, &contents);
3207                 if (r < 0) {
3208                         log_error("Failed to peek type: %s", strerror(-r));
3209                         return r;
3210                 }
3211                 if (r == 0) {
3212                         if (level <= 1)
3213                                 break;
3214
3215                         r = sd_bus_message_exit_container(m);
3216                         if (r < 0) {
3217                                 log_error("Failed to exit container: %s", strerror(-r));
3218                                 return r;
3219                         }
3220
3221                         level--;
3222
3223                         prefix = strrep("\t", level);
3224                         if (!prefix)
3225                                 return log_oom();
3226
3227                         if (type == SD_BUS_TYPE_ARRAY)
3228                                 printf("%s} END_ARRAY \n", prefix);
3229                         else if (type == SD_BUS_TYPE_VARIANT)
3230                                 printf("%s} END_VARIANT\n", prefix);
3231                         else if (type == SD_BUS_TYPE_STRUCT)
3232                                 printf("%s} END_STRUCT\n", prefix);
3233                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3234                                 printf("%s} END_DICT_ENTRY\n", prefix);
3235
3236                         continue;
3237                 }
3238
3239                 prefix = strrep("\t", level);
3240                 if (!prefix)
3241                         return log_oom();
3242
3243                 if (bus_type_is_container(type) > 0) {
3244                         r = sd_bus_message_enter_container(m, type, contents);
3245                         if (r < 0) {
3246                                 log_error("Failed to enter container: %s", strerror(-r));
3247                                 return r;
3248                         }
3249
3250                         if (type == SD_BUS_TYPE_ARRAY)
3251                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3252                         else if (type == SD_BUS_TYPE_VARIANT)
3253                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3254                         else if (type == SD_BUS_TYPE_STRUCT)
3255                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3256                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3257                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3258
3259                         level ++;
3260
3261                         continue;
3262                 }
3263
3264                 r = sd_bus_message_read_basic(m, type, &basic);
3265                 if (r < 0) {
3266                         log_error("Failed to get basic: %s", strerror(-r));
3267                         return r;
3268                 }
3269
3270                 switch (type) {
3271
3272                 case SD_BUS_TYPE_BYTE:
3273                         printf("%sBYTE: %u\n", prefix, basic.u8);
3274                         break;
3275
3276                 case SD_BUS_TYPE_BOOLEAN:
3277                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3278                         break;
3279
3280                 case SD_BUS_TYPE_INT16:
3281                         printf("%sINT16: %i\n", prefix, basic.s16);
3282                         break;
3283
3284                 case SD_BUS_TYPE_UINT16:
3285                         printf("%sUINT16: %u\n", prefix, basic.u16);
3286                         break;
3287
3288                 case SD_BUS_TYPE_INT32:
3289                         printf("%sINT32: %i\n", prefix, basic.s32);
3290                         break;
3291
3292                 case SD_BUS_TYPE_UINT32:
3293                         printf("%sUINT32: %u\n", prefix, basic.u32);
3294                         break;
3295
3296                 case SD_BUS_TYPE_INT64:
3297                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3298                         break;
3299
3300                 case SD_BUS_TYPE_UINT64:
3301                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3302                         break;
3303
3304                 case SD_BUS_TYPE_DOUBLE:
3305                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
3306                         break;
3307
3308                 case SD_BUS_TYPE_STRING:
3309                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3310                         break;
3311
3312                 case SD_BUS_TYPE_OBJECT_PATH:
3313                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3314                         break;
3315
3316                 case SD_BUS_TYPE_SIGNATURE:
3317                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3318                         break;
3319
3320                 case SD_BUS_TYPE_UNIX_FD:
3321                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
3322                         break;
3323
3324                 default:
3325                         assert_not_reached("Unknown basic type.");
3326                 }
3327         }
3328
3329         printf("} END_MESSAGE\n");
3330         return 0;
3331 }
3332
3333 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3334         size_t total;
3335         void *p, *e;
3336
3337         assert(m);
3338         assert(buffer);
3339         assert(sz);
3340
3341         total = BUS_MESSAGE_SIZE(m);
3342
3343         p = malloc(total);
3344         if (!p)
3345                 return -ENOMEM;
3346
3347         e = mempcpy(p, m->header, sizeof(*m->header));
3348
3349         if (m->fields) {
3350                 e = mempcpy(e, m->fields, m->header->fields_size);
3351
3352                 if (m->header->fields_size % 8 != 0)
3353                         e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3354         }
3355
3356         if (m->body)
3357                 e = mempcpy(e, m->body, m->header->body_size);
3358
3359         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3360
3361         *buffer = p;
3362         *sz = total;
3363
3364         return 0;
3365 }
3366
3367 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3368         int r;
3369
3370         assert(m);
3371         assert(l);
3372
3373         r = sd_bus_message_enter_container(m, 'a', "s");
3374         if (r < 0)
3375                 return r;
3376
3377         for (;;) {
3378                 const char *s;
3379
3380                 r = sd_bus_message_read_basic(m, 's', &s);
3381                 if (r < 0)
3382                         return r;
3383                 if (r == 0)
3384                         break;
3385
3386                 r = strv_extend(l, s);
3387                 if (r < 0)
3388                         return r;
3389         }
3390
3391         r = sd_bus_message_exit_container(m);
3392         if (r < 0)
3393                 return r;
3394
3395         return 0;
3396 }
3397
3398 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3399         int r;
3400         const char *t = NULL;
3401         unsigned j;
3402
3403         assert(m);
3404
3405         r = sd_bus_message_rewind(m, true);
3406         if (r < 0)
3407                 return NULL;
3408
3409         for (j = 0; j <= i; j++) {
3410                 char type;
3411
3412                 r = sd_bus_message_peek_type(m, &type, NULL);
3413                 if (r < 0)
3414                         return NULL;
3415
3416                 if (type != SD_BUS_TYPE_STRING &&
3417                     type != SD_BUS_TYPE_OBJECT_PATH &&
3418                     type != SD_BUS_TYPE_SIGNATURE)
3419                         return NULL;
3420
3421                 r = sd_bus_message_read_basic(m, type, &t);
3422                 if (r < 0)
3423                         return NULL;
3424         }
3425
3426         return t;
3427 }
3428
3429 int bus_header_size(struct bus_header *h, size_t *sum) {
3430         size_t fs, bs;
3431
3432         assert(h);
3433         assert(sum);
3434
3435         if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3436                 fs = h->fields_size;
3437                 bs = h->body_size;
3438         } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3439                 fs = bswap_32(h->fields_size);
3440                 bs = bswap_32(h->body_size);
3441         } else
3442                 return -EBADMSG;
3443
3444         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
3445         return 0;
3446 }