chiark / gitweb /
6b4a0f343256cd5db23d9056dbf0b78e034bde61
[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_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
908         if (!m)
909                 return -EINVAL;
910         if (!sessionid)
911                 return -EINVAL;
912         if (!m->audit)
913                 return -ESRCH;
914
915         *sessionid = m->audit->sessionid;
916         return 0;
917 }
918
919 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
920         if (!m)
921                 return -EINVAL;
922         if (!uid)
923                 return -EINVAL;
924         if (!m->audit)
925                 return -ESRCH;
926
927         *uid = m->audit->loginuid;
928         return 0;
929 }
930
931 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
932         if (!m)
933                 return -EINVAL;
934
935         if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
936                 return 0;
937
938         if (interface && (!m->interface || !streq(m->interface, interface)))
939                 return 0;
940
941         if (member &&  (!m->member || !streq(m->member, member)))
942                 return 0;
943
944         return 1;
945 }
946
947 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
948         if (!m)
949                 return -EINVAL;
950
951         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
952                 return 0;
953
954         if (interface && (!m->interface || !streq(m->interface, interface)))
955                 return 0;
956
957         if (member &&  (!m->member || !streq(m->member, member)))
958                 return 0;
959
960         return 1;
961 }
962
963 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
964         if (!m)
965                 return -EINVAL;
966
967         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
968                 return 0;
969
970         if (name && (!m->error.name || !streq(m->error.name, name)))
971                 return 0;
972
973         return 1;
974 }
975
976 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
977         if (!m)
978                 return -EINVAL;
979         if (m->sealed)
980                 return -EPERM;
981         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
982                 return -EPERM;
983
984         if (b)
985                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
986         else
987                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
988
989         return 0;
990 }
991
992 static struct bus_container *message_get_container(sd_bus_message *m) {
993         assert(m);
994
995         if (m->n_containers == 0)
996                 return &m->root_container;
997
998         assert(m->containers);
999         return m->containers + m->n_containers - 1;
1000 }
1001
1002 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1003         void *p, *o;
1004         size_t added;
1005         struct bus_container *c;
1006
1007         assert(m);
1008         assert(align > 0);
1009
1010         o = m->body;
1011         added = m->header->body_size;
1012
1013         p = buffer_extend(&m->body, &m->header->body_size, align, sz);
1014         if (!p)
1015                 return NULL;
1016
1017         added = m->header->body_size - added;
1018
1019         for (c = m->containers; c < m->containers + m->n_containers; c++)
1020                 if (c->array_size) {
1021                         c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
1022                         *c->array_size += added;
1023                 }
1024
1025         if (o != m->body) {
1026                 if (m->error.message)
1027                         m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
1028         }
1029
1030         m->free_body = true;
1031
1032         return p;
1033 }
1034
1035 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1036         struct bus_container *c;
1037         ssize_t align, sz;
1038         uint32_t k;
1039         void *a;
1040         char *e = NULL;
1041         int fd = -1;
1042         uint32_t fdi = 0;
1043         int r;
1044
1045         if (!m)
1046                 return -EINVAL;
1047         if (!p)
1048                 return -EINVAL;
1049         if (m->sealed)
1050                 return -EPERM;
1051         if (!bus_type_is_basic(type))
1052                 return -EINVAL;
1053
1054         c = message_get_container(m);
1055
1056         if (c->signature && c->signature[c->index]) {
1057                 /* Container signature is already set */
1058
1059                 if (c->signature[c->index] != type)
1060                         return -ENXIO;
1061         } else {
1062                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1063                 if (c->enclosing != 0)
1064                         return -ENXIO;
1065
1066                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1067                 if (!e)
1068                         return -ENOMEM;
1069         }
1070
1071         switch (type) {
1072
1073         case SD_BUS_TYPE_STRING:
1074         case SD_BUS_TYPE_OBJECT_PATH:
1075
1076                 align = 4;
1077                 sz = 4 + strlen(p) + 1;
1078                 break;
1079
1080         case SD_BUS_TYPE_SIGNATURE:
1081
1082                 align = 1;
1083                 sz = 1 + strlen(p) + 1;
1084                 break;
1085
1086         case SD_BUS_TYPE_BOOLEAN:
1087                 align = sz = 4;
1088
1089                 assert_cc(sizeof(int) == sizeof(uint32_t));
1090                 memcpy(&k, p, 4);
1091                 k = !!k;
1092                 p = &k;
1093                 break;
1094
1095         case SD_BUS_TYPE_UNIX_FD: {
1096                 int z, *f;
1097
1098                 if (!m->allow_fds) {
1099                         r = -ENOTSUP;
1100                         goto fail;
1101                 }
1102
1103                 align = sz = 4;
1104
1105                 z = *(int*) p;
1106                 if (z < 0) {
1107                         r = -EINVAL;
1108                         goto fail;
1109                 }
1110
1111                 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1112                 if (fd < 0) {
1113                         r = -errno;
1114                         goto fail;
1115                 }
1116
1117                 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1118                 if (!f) {
1119                         r = -ENOMEM;
1120                         goto fail;
1121                 }
1122
1123                 fdi = m->n_fds;
1124                 f[fdi] = fd;
1125                 m->fds = f;
1126                 m->free_fds = true;
1127                 break;
1128         }
1129
1130         default:
1131                 align = bus_type_get_alignment(type);
1132                 sz = bus_type_get_size(type);
1133                 break;
1134         }
1135
1136         assert(align > 0);
1137         assert(sz > 0);
1138
1139         a = message_extend_body(m, align, sz);
1140         if (!a) {
1141                 r = -ENOMEM;
1142                 goto fail;
1143         }
1144
1145         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1146                 *(uint32_t*) a = sz - 5;
1147                 memcpy((uint8_t*) a + 4, p, sz - 4);
1148
1149                 if (stored)
1150                         *stored = (const uint8_t*) a + 4;
1151
1152         } else if (type == SD_BUS_TYPE_SIGNATURE) {
1153                 *(uint8_t*) a = sz - 1;
1154                 memcpy((uint8_t*) a + 1, p, sz - 1);
1155
1156                 if (stored)
1157                         *stored = (const uint8_t*) a + 1;
1158         } else if (type == SD_BUS_TYPE_UNIX_FD) {
1159                 *(uint32_t*) a = fdi;
1160
1161                 if (stored)
1162                         *stored = a;
1163
1164                 m->n_fds ++;
1165
1166         } else {
1167                 memcpy(a, p, sz);
1168
1169                 if (stored)
1170                         *stored = a;
1171         }
1172
1173         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1174                 c->index++;
1175
1176         return 0;
1177
1178 fail:
1179         /* Truncate extended signature again */
1180         if (e)
1181                 c->signature[c->index] = 0;
1182
1183         if (fd >= 0)
1184                 close_nointr_nofail(fd);
1185
1186         return r;
1187 }
1188
1189 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1190         return message_append_basic(m, type, p, NULL);
1191 }
1192
1193 static int bus_message_open_array(
1194                 sd_bus_message *m,
1195                 struct bus_container *c,
1196                 const char *contents,
1197                 uint32_t **array_size) {
1198
1199         unsigned nindex;
1200         char *e = NULL;
1201         void *a, *b;
1202         int alignment;
1203         size_t saved;
1204
1205         assert(m);
1206         assert(c);
1207         assert(contents);
1208         assert(array_size);
1209
1210         if (!signature_is_single(contents))
1211                 return -EINVAL;
1212
1213         alignment = bus_type_get_alignment(contents[0]);
1214         if (alignment < 0)
1215                 return alignment;
1216
1217         if (c->signature && c->signature[c->index]) {
1218
1219                 /* Verify the existing signature */
1220
1221                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1222                         return -ENXIO;
1223
1224                 if (!startswith(c->signature + c->index + 1, contents))
1225                         return -ENXIO;
1226
1227                 nindex = c->index + 1 + strlen(contents);
1228         } else {
1229                 if (c->enclosing != 0)
1230                         return -ENXIO;
1231
1232                 /* Extend the existing signature */
1233
1234                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1235                 if (!e)
1236                         return -ENOMEM;
1237
1238                 nindex = e - c->signature;
1239         }
1240
1241         saved = m->header->body_size;
1242         a = message_extend_body(m, 4, 4);
1243         if (!a) {
1244                 /* Truncate extended signature again */
1245                 if (e)
1246                         c->signature[c->index] = 0;
1247
1248                 return -ENOMEM;
1249         }
1250         b = m->body;
1251
1252         if (!message_extend_body(m, alignment, 0)) {
1253                 /* Add alignment between size and first element */
1254                 if (e)
1255                         c->signature[c->index] = 0;
1256
1257                 m->header->body_size = saved;
1258                 return -ENOMEM;
1259         }
1260
1261         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1262                 c->index = nindex;
1263
1264         /* m->body might have changed so let's readjust a */
1265         a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1266         *(uint32_t*) a = 0;
1267
1268         *array_size = a;
1269         return 0;
1270 }
1271
1272 static int bus_message_open_variant(
1273                 sd_bus_message *m,
1274                 struct bus_container *c,
1275                 const char *contents) {
1276
1277         char *e = NULL;
1278         size_t l;
1279         void *a;
1280
1281         assert(m);
1282         assert(c);
1283         assert(contents);
1284
1285         if (!signature_is_single(contents))
1286                 return -EINVAL;
1287
1288         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1289                 return -EINVAL;
1290
1291         if (c->signature && c->signature[c->index]) {
1292
1293                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1294                         return -ENXIO;
1295
1296         } else {
1297                 if (c->enclosing != 0)
1298                         return -ENXIO;
1299
1300                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1301                 if (!e)
1302                         return -ENOMEM;
1303         }
1304
1305         l = strlen(contents);
1306         a = message_extend_body(m, 1, 1 + l + 1);
1307         if (!a) {
1308                 /* Truncate extended signature again */
1309                 if (e)
1310                         c->signature[c->index] = 0;
1311
1312                 return -ENOMEM;
1313         }
1314
1315         *(uint8_t*) a = l;
1316         memcpy((uint8_t*) a + 1, contents, l + 1);
1317
1318         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1319                 c->index++;
1320
1321         return 0;
1322 }
1323
1324 static int bus_message_open_struct(
1325                 sd_bus_message *m,
1326                 struct bus_container *c,
1327                 const char *contents) {
1328
1329         size_t nindex;
1330         char *e = NULL;
1331
1332         assert(m);
1333         assert(c);
1334         assert(contents);
1335
1336         if (!signature_is_valid(contents, false))
1337                 return -EINVAL;
1338
1339         if (c->signature && c->signature[c->index]) {
1340                 size_t l;
1341
1342                 l = strlen(contents);
1343
1344                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1345                     !startswith(c->signature + c->index + 1, contents) ||
1346                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1347                         return -ENXIO;
1348
1349                 nindex = c->index + 1 + l + 1;
1350         } else {
1351                 if (c->enclosing != 0)
1352                         return -ENXIO;
1353
1354                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1355                 if (!e)
1356                         return -ENOMEM;
1357
1358                 nindex = e - c->signature;
1359         }
1360
1361         /* Align contents to 8 byte boundary */
1362         if (!message_extend_body(m, 8, 0)) {
1363                 if (e)
1364                         c->signature[c->index] = 0;
1365
1366                 return -ENOMEM;
1367         }
1368
1369         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1370                 c->index = nindex;
1371
1372         return 0;
1373 }
1374
1375 static int bus_message_open_dict_entry(
1376                 sd_bus_message *m,
1377                 struct bus_container *c,
1378                 const char *contents) {
1379
1380         size_t nindex;
1381
1382         assert(m);
1383         assert(c);
1384         assert(contents);
1385
1386         if (!signature_is_pair(contents))
1387                 return -EINVAL;
1388
1389         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1390                 return -ENXIO;
1391
1392         if (c->signature && c->signature[c->index]) {
1393                 size_t l;
1394
1395                 l = strlen(contents);
1396
1397                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1398                     !startswith(c->signature + c->index + 1, contents) ||
1399                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1400                         return -ENXIO;
1401
1402                 nindex = c->index + 1 + l + 1;
1403         } else
1404                 return -ENXIO;
1405
1406         /* Align contents to 8 byte boundary */
1407         if (!message_extend_body(m, 8, 0))
1408                 return -ENOMEM;
1409
1410         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1411                 c->index = nindex;
1412
1413         return 0;
1414 }
1415
1416 int sd_bus_message_open_container(
1417                 sd_bus_message *m,
1418                 char type,
1419                 const char *contents) {
1420
1421         struct bus_container *c, *w;
1422         uint32_t *array_size = NULL;
1423         char *signature;
1424         int r;
1425
1426         if (!m)
1427                 return -EINVAL;
1428         if (m->sealed)
1429                 return -EPERM;
1430         if (!contents)
1431                 return -EINVAL;
1432
1433         /* Make sure we have space for one more container */
1434         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1435         if (!w)
1436                 return -ENOMEM;
1437         m->containers = w;
1438
1439         c = message_get_container(m);
1440
1441         signature = strdup(contents);
1442         if (!signature)
1443                 return -ENOMEM;
1444
1445         if (type == SD_BUS_TYPE_ARRAY)
1446                 r = bus_message_open_array(m, c, contents, &array_size);
1447         else if (type == SD_BUS_TYPE_VARIANT)
1448                 r = bus_message_open_variant(m, c, contents);
1449         else if (type == SD_BUS_TYPE_STRUCT)
1450                 r = bus_message_open_struct(m, c, contents);
1451         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1452                 r = bus_message_open_dict_entry(m, c, contents);
1453         else
1454                 r = -EINVAL;
1455
1456         if (r < 0) {
1457                 free(signature);
1458                 return r;
1459         }
1460
1461         /* OK, let's fill it in */
1462         w += m->n_containers++;
1463         w->enclosing = type;
1464         w->signature = signature;
1465         w->index = 0;
1466         w->array_size = array_size;
1467         w->begin = 0;
1468
1469         return 0;
1470 }
1471
1472 int sd_bus_message_close_container(sd_bus_message *m) {
1473         struct bus_container *c;
1474
1475         if (!m)
1476                 return -EINVAL;
1477         if (m->sealed)
1478                 return -EPERM;
1479         if (m->n_containers <= 0)
1480                 return -EINVAL;
1481
1482         c = message_get_container(m);
1483         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1484                 if (c->signature && c->signature[c->index] != 0)
1485                         return -EINVAL;
1486
1487         free(c->signature);
1488         m->n_containers--;
1489
1490         return 0;
1491 }
1492
1493
1494 typedef struct {
1495         const char *types;
1496         unsigned n_struct;
1497         unsigned n_array;
1498 } TypeStack;
1499
1500 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1501         assert(stack);
1502         assert(max > 0);
1503
1504         if (*i >= max)
1505                 return -EINVAL;
1506
1507         stack[*i].types = types;
1508         stack[*i].n_struct = n_struct;
1509         stack[*i].n_array = n_array;
1510         (*i)++;
1511
1512         return 0;
1513 }
1514
1515 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1516         assert(stack);
1517         assert(max > 0);
1518         assert(types);
1519         assert(n_struct);
1520         assert(n_array);
1521
1522         if (*i <= 0)
1523                 return 0;
1524
1525         (*i)--;
1526         *types = stack[*i].types;
1527         *n_struct = stack[*i].n_struct;
1528         *n_array = stack[*i].n_array;
1529
1530         return 1;
1531 }
1532
1533 int bus_message_append_ap(
1534                 sd_bus_message *m,
1535                 const char *types,
1536                 va_list ap) {
1537
1538         unsigned n_array, n_struct;
1539         TypeStack stack[BUS_CONTAINER_DEPTH];
1540         unsigned stack_ptr = 0;
1541         int r;
1542
1543         assert(m);
1544
1545         if (!types)
1546                 return 0;
1547
1548         n_array = (unsigned) -1;
1549         n_struct = strlen(types);
1550
1551         for (;;) {
1552                 const char *t;
1553
1554                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1555                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1556                         if (r < 0)
1557                                 return r;
1558                         if (r == 0)
1559                                 break;
1560
1561                         r = sd_bus_message_close_container(m);
1562                         if (r < 0)
1563                                 return r;
1564
1565                         continue;
1566                 }
1567
1568                 t = types;
1569                 if (n_array != (unsigned) -1)
1570                         n_array --;
1571                 else {
1572                         types ++;
1573                         n_struct--;
1574                 }
1575
1576                 switch (*t) {
1577
1578                 case SD_BUS_TYPE_BYTE: {
1579                         uint8_t x;
1580
1581                         x = (uint8_t) va_arg(ap, int);
1582                         r = sd_bus_message_append_basic(m, *t, &x);
1583                         break;
1584                 }
1585
1586                 case SD_BUS_TYPE_BOOLEAN:
1587                 case SD_BUS_TYPE_INT32:
1588                 case SD_BUS_TYPE_UINT32:
1589                 case SD_BUS_TYPE_UNIX_FD: {
1590                         uint32_t x;
1591
1592                         /* We assume a boolean is the same as int32_t */
1593                         assert_cc(sizeof(int32_t) == sizeof(int));
1594
1595                         x = va_arg(ap, uint32_t);
1596                         r = sd_bus_message_append_basic(m, *t, &x);
1597                         break;
1598                 }
1599
1600                 case SD_BUS_TYPE_INT16:
1601                 case SD_BUS_TYPE_UINT16: {
1602                         uint16_t x;
1603
1604                         x = (uint16_t) va_arg(ap, int);
1605                         r = sd_bus_message_append_basic(m, *t, &x);
1606                         break;
1607                 }
1608
1609                 case SD_BUS_TYPE_INT64:
1610                 case SD_BUS_TYPE_UINT64:
1611                 case SD_BUS_TYPE_DOUBLE: {
1612                         uint64_t x;
1613
1614                         x = va_arg(ap, uint64_t);
1615                         r = sd_bus_message_append_basic(m, *t, &x);
1616                         break;
1617                 }
1618
1619                 case SD_BUS_TYPE_STRING:
1620                 case SD_BUS_TYPE_OBJECT_PATH:
1621                 case SD_BUS_TYPE_SIGNATURE: {
1622                         const char *x;
1623
1624                         x = va_arg(ap, const char*);
1625                         r = sd_bus_message_append_basic(m, *t, x);
1626                         break;
1627                 }
1628
1629                 case SD_BUS_TYPE_ARRAY: {
1630                         size_t k;
1631
1632                         r = signature_element_length(t + 1, &k);
1633                         if (r < 0)
1634                                 return r;
1635
1636                         {
1637                                 char s[k + 1];
1638                                 memcpy(s, t + 1, k);
1639                                 s[k] = 0;
1640
1641                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1642                                 if (r < 0)
1643                                         return r;
1644                         }
1645
1646                         if (n_array == (unsigned) -1) {
1647                                 types += k;
1648                                 n_struct -= k;
1649                         }
1650
1651                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1652                         if (r < 0)
1653                                 return r;
1654
1655                         types = t + 1;
1656                         n_struct = k;
1657                         n_array = va_arg(ap, unsigned);
1658
1659                         break;
1660                 }
1661
1662                 case SD_BUS_TYPE_VARIANT: {
1663                         const char *s;
1664
1665                         s = va_arg(ap, const char*);
1666                         if (!s)
1667                                 return -EINVAL;
1668
1669                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1670                         if (r < 0)
1671                                 return r;
1672
1673                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1674                         if (r < 0)
1675                                 return r;
1676
1677                         types = s;
1678                         n_struct = strlen(s);
1679                         n_array = (unsigned) -1;
1680
1681                         break;
1682                 }
1683
1684                 case SD_BUS_TYPE_STRUCT_BEGIN:
1685                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1686                         size_t k;
1687
1688                         r = signature_element_length(t, &k);
1689                         if (r < 0)
1690                                 return r;
1691
1692                         {
1693                                 char s[k - 1];
1694
1695                                 memcpy(s, t + 1, k - 2);
1696                                 s[k - 2] = 0;
1697
1698                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1699                                 if (r < 0)
1700                                         return r;
1701                         }
1702
1703                         if (n_array == (unsigned) -1) {
1704                                 types += k - 1;
1705                                 n_struct -= k - 1;
1706                         }
1707
1708                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1709                         if (r < 0)
1710                                 return r;
1711
1712                         types = t + 1;
1713                         n_struct = k - 2;
1714                         n_array = (unsigned) -1;
1715
1716                         break;
1717                 }
1718
1719                 default:
1720                         r = -EINVAL;
1721                 }
1722
1723                 if (r < 0)
1724                         return r;
1725         }
1726
1727         return 0;
1728 }
1729
1730 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1731         va_list ap;
1732         int r;
1733
1734         if (!m)
1735                 return -EINVAL;
1736         if (m->sealed)
1737                 return -EPERM;
1738         if (!types)
1739                 return 0;
1740
1741         va_start(ap, types);
1742         r = bus_message_append_ap(m, types, ap);
1743         va_end(ap);
1744
1745         return r;
1746 }
1747
1748 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1749         size_t k, start, n;
1750
1751         assert(rindex);
1752         assert(align > 0);
1753
1754         start = ALIGN_TO((size_t) *rindex, align);
1755         n = start + nbytes;
1756
1757         if (n > sz)
1758                 return -EBADMSG;
1759
1760         /* Verify that padding is 0 */
1761         for (k = *rindex; k < start; k++)
1762                 if (((const uint8_t*) p)[k] != 0)
1763                         return -EBADMSG;
1764
1765         if (r)
1766                 *r = (uint8_t*) p + start;
1767
1768         *rindex = n;
1769
1770         return 1;
1771 }
1772
1773 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1774         struct bus_container *c;
1775
1776         assert(m);
1777
1778         c = message_get_container(m);
1779         if (!c->array_size)
1780                 return false;
1781
1782         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1783 }
1784
1785 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1786         assert(m);
1787         assert(rindex);
1788         assert(align > 0);
1789
1790         if (message_end_of_array(m, *rindex))
1791                 return 0;
1792
1793         return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1794 }
1795
1796 static bool validate_nul(const char *s, size_t l) {
1797
1798         /* Check for NUL chars in the string */
1799         if (memchr(s, 0, l))
1800                 return false;
1801
1802         /* Check for NUL termination */
1803         if (s[l] != 0)
1804                 return false;
1805
1806         return true;
1807 }
1808
1809 static bool validate_string(const char *s, size_t l) {
1810
1811         if (!validate_nul(s, l))
1812                 return false;
1813
1814         /* Check if valid UTF8 */
1815         if (!utf8_is_valid(s))
1816                 return false;
1817
1818         return true;
1819 }
1820
1821 static bool validate_signature(const char *s, size_t l) {
1822
1823         if (!validate_nul(s, l))
1824                 return false;
1825
1826         /* Check if valid signature */
1827         if (!signature_is_valid(s, true))
1828                 return false;
1829
1830         return true;
1831 }
1832
1833 static bool validate_object_path(const char *s, size_t l) {
1834
1835         if (!validate_nul(s, l))
1836                 return false;
1837
1838         if (!object_path_is_valid(s))
1839                 return false;
1840
1841         return true;
1842 }
1843
1844 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1845         struct bus_container *c;
1846         int r;
1847         void *q;
1848
1849         if (!m)
1850                 return -EINVAL;
1851         if (!m->sealed)
1852                 return -EPERM;
1853         if (!bus_type_is_basic(type))
1854                 return -EINVAL;
1855         if (!p)
1856                 return -EINVAL;
1857
1858         c = message_get_container(m);
1859
1860         if (!c->signature || c->signature[c->index] == 0)
1861                 return 0;
1862
1863         if (c->signature[c->index] != type)
1864                 return -ENXIO;
1865
1866         switch (type) {
1867
1868         case SD_BUS_TYPE_STRING:
1869         case SD_BUS_TYPE_OBJECT_PATH: {
1870                 uint32_t l;
1871                 size_t rindex;
1872
1873                 rindex = m->rindex;
1874                 r = message_peek_body(m, &rindex, 4, 4, &q);
1875                 if (r <= 0)
1876                         return r;
1877
1878                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1879                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1880                 if (r < 0)
1881                         return r;
1882                 if (r == 0)
1883                         return -EBADMSG;
1884
1885                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1886                         if (!validate_object_path(q, l))
1887                                 return -EBADMSG;
1888                 } else {
1889                         if (!validate_string(q, l))
1890                                 return -EBADMSG;
1891                 }
1892
1893                 m->rindex = rindex;
1894                 *(const char**) p = q;
1895                 break;
1896         }
1897
1898         case SD_BUS_TYPE_SIGNATURE: {
1899                 uint8_t l;
1900                 size_t rindex;
1901
1902                 rindex = m->rindex;
1903                 r = message_peek_body(m, &rindex, 1, 1, &q);
1904                 if (r <= 0)
1905                         return r;
1906
1907                 l = *(uint8_t*) q;
1908                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1909                 if (r < 0)
1910                         return r;
1911                 if (r == 0)
1912                         return -EBADMSG;
1913
1914                 if (!validate_signature(q, l))
1915                         return -EBADMSG;
1916
1917                 m->rindex = rindex;
1918                 *(const char**) p = q;
1919                 break;
1920         }
1921
1922         default: {
1923                 ssize_t sz, align;
1924                 size_t rindex;
1925
1926                 align = bus_type_get_alignment(type);
1927                 sz = bus_type_get_size(type);
1928                 assert(align > 0 && sz > 0);
1929
1930                 rindex = m->rindex;
1931                 r = message_peek_body(m, &rindex, align, sz, &q);
1932                 if (r <= 0)
1933                         return r;
1934
1935                 switch (type) {
1936
1937                 case SD_BUS_TYPE_BYTE:
1938                         *(uint8_t*) p = *(uint8_t*) q;
1939                         break;
1940
1941                 case SD_BUS_TYPE_BOOLEAN:
1942                         *(int*) p = !!*(uint32_t*) q;
1943                         break;
1944
1945                 case SD_BUS_TYPE_INT16:
1946                 case SD_BUS_TYPE_UINT16:
1947                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1948                         break;
1949
1950                 case SD_BUS_TYPE_INT32:
1951                 case SD_BUS_TYPE_UINT32:
1952                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1953                         break;
1954
1955                 case SD_BUS_TYPE_INT64:
1956                 case SD_BUS_TYPE_UINT64:
1957                 case SD_BUS_TYPE_DOUBLE:
1958                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1959                         break;
1960
1961                 case SD_BUS_TYPE_UNIX_FD: {
1962                         uint32_t j;
1963
1964                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1965                         if (j >= m->n_fds)
1966                                 return -EBADMSG;
1967
1968                         *(int*) p = m->fds[j];
1969                         break;
1970                 }
1971
1972                 default:
1973                         assert_not_reached("Unknown basic type...");
1974                 }
1975
1976                         m->rindex = rindex;
1977
1978                 break;
1979         }
1980         }
1981
1982         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1983                 c->index++;
1984
1985         return 1;
1986 }
1987
1988 static int bus_message_enter_array(
1989                 sd_bus_message *m,
1990                 struct bus_container *c,
1991                 const char *contents,
1992                 uint32_t **array_size) {
1993
1994         size_t rindex;
1995         void *q;
1996         int r, alignment;
1997
1998         assert(m);
1999         assert(c);
2000         assert(contents);
2001         assert(array_size);
2002
2003         if (!signature_is_single(contents))
2004                 return -EINVAL;
2005
2006         alignment = bus_type_get_alignment(contents[0]);
2007         if (alignment < 0)
2008                 return alignment;
2009
2010         if (!c->signature || c->signature[c->index] == 0)
2011                 return 0;
2012
2013         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2014                 return -ENXIO;
2015
2016         if (!startswith(c->signature + c->index + 1, contents))
2017                 return -ENXIO;
2018
2019         rindex = m->rindex;
2020         r = message_peek_body(m, &rindex, 4, 4, &q);
2021         if (r <= 0)
2022                 return r;
2023
2024         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2025                 return -EBADMSG;
2026
2027         r = message_peek_body(m, &rindex, alignment, 0, NULL);
2028         if (r < 0)
2029                 return r;
2030         if (r == 0)
2031                 return -EBADMSG;
2032
2033         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2034                 c->index += 1 + strlen(contents);
2035
2036         m->rindex = rindex;
2037
2038         *array_size = (uint32_t*) q;
2039
2040         return 1;
2041 }
2042
2043 static int bus_message_enter_variant(
2044                 sd_bus_message *m,
2045                 struct bus_container *c,
2046                 const char *contents) {
2047
2048         size_t rindex;
2049         uint8_t l;
2050         void *q;
2051         int r;
2052
2053         assert(m);
2054         assert(c);
2055         assert(contents);
2056
2057         if (!signature_is_single(contents))
2058                 return -EINVAL;
2059
2060         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2061                 return -EINVAL;
2062
2063         if (!c->signature || c->signature[c->index] == 0)
2064                 return 0;
2065
2066         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2067                 return -ENXIO;
2068
2069         rindex = m->rindex;
2070         r = message_peek_body(m, &rindex, 1, 1, &q);
2071         if (r <= 0)
2072                 return r;
2073
2074         l = *(uint8_t*) q;
2075         r = message_peek_body(m, &rindex, 1, l+1, &q);
2076         if (r < 0)
2077                 return r;
2078         if (r == 0)
2079                 return -EBADMSG;
2080
2081         if (!validate_signature(q, l))
2082                 return -EBADMSG;
2083
2084         if (!streq(q, contents))
2085                 return -ENXIO;
2086
2087         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2088                 c->index++;
2089
2090         m->rindex = rindex;
2091
2092         return 1;
2093 }
2094
2095 static int bus_message_enter_struct(
2096                 sd_bus_message *m,
2097                 struct bus_container *c,
2098                 const char *contents) {
2099
2100         size_t l;
2101         int r;
2102
2103         assert(m);
2104         assert(c);
2105         assert(contents);
2106
2107         if (!signature_is_valid(contents, false))
2108                 return -EINVAL;
2109
2110         if (!c->signature || c->signature[c->index] == 0)
2111                 return 0;
2112
2113         l = strlen(contents);
2114
2115         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2116             !startswith(c->signature + c->index + 1, contents) ||
2117             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2118                 return -ENXIO;
2119
2120         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2121         if (r <= 0)
2122                 return r;
2123
2124         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2125                 c->index += 1 + l + 1;
2126
2127         return 1;
2128 }
2129
2130 static int bus_message_enter_dict_entry(
2131                 sd_bus_message *m,
2132                 struct bus_container *c,
2133                 const char *contents) {
2134
2135         size_t l;
2136         int r;
2137
2138         assert(m);
2139         assert(c);
2140         assert(contents);
2141
2142         if (!signature_is_pair(contents))
2143                 return -EINVAL;
2144
2145         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2146                 return -ENXIO;
2147
2148         if (!c->signature || c->signature[c->index] == 0)
2149                 return 0;
2150
2151         l = strlen(contents);
2152
2153         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2154             !startswith(c->signature + c->index + 1, contents) ||
2155             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2156                 return -ENXIO;
2157
2158         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2159         if (r <= 0)
2160                 return r;
2161
2162         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2163                 c->index += 1 + l + 1;
2164
2165         return 1;
2166 }
2167
2168 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2169         struct bus_container *c, *w;
2170         uint32_t *array_size = NULL;
2171         char *signature;
2172         int r;
2173
2174         if (!m)
2175                 return -EINVAL;
2176         if (!m->sealed)
2177                 return -EPERM;
2178         if (!contents)
2179                 return -EINVAL;
2180
2181         /*
2182          * We enforce a global limit on container depth, that is much
2183          * higher than the 32 structs and 32 arrays the specification
2184          * mandates. This is simpler to implement for us, and we need
2185          * this only to ensure our container array doesn't grow
2186          * without bounds. We are happy to return any data from a
2187          * message as long as the data itself is valid, even if the
2188          * overall message might be not.
2189          *
2190          * Note that the message signature is validated when
2191          * parsing the headers, and that validation does check the
2192          * 32/32 limit.
2193          *
2194          * Note that the specification defines no limits on the depth
2195          * of stacked variants, but we do.
2196          */
2197         if (m->n_containers >= BUS_CONTAINER_DEPTH)
2198                 return -EBADMSG;
2199
2200         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2201         if (!w)
2202                 return -ENOMEM;
2203         m->containers = w;
2204
2205         c = message_get_container(m);
2206
2207         if (!c->signature || c->signature[c->index] == 0)
2208                 return 0;
2209
2210         signature = strdup(contents);
2211         if (!signature)
2212                 return -ENOMEM;
2213
2214         if (type == SD_BUS_TYPE_ARRAY)
2215                 r = bus_message_enter_array(m, c, contents, &array_size);
2216         else if (type == SD_BUS_TYPE_VARIANT)
2217                 r = bus_message_enter_variant(m, c, contents);
2218         else if (type == SD_BUS_TYPE_STRUCT)
2219                 r = bus_message_enter_struct(m, c, contents);
2220         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2221                 r = bus_message_enter_dict_entry(m, c, contents);
2222         else
2223                 r = -EINVAL;
2224
2225         if (r <= 0) {
2226                 free(signature);
2227                 return r;
2228         }
2229
2230         /* OK, let's fill it in */
2231         w += m->n_containers++;
2232         w->enclosing = type;
2233         w->signature = signature;
2234         w->index = 0;
2235         w->array_size = array_size;
2236         w->begin = m->rindex;
2237
2238         return 1;
2239 }
2240
2241 int sd_bus_message_exit_container(sd_bus_message *m) {
2242         struct bus_container *c;
2243
2244         if (!m)
2245                 return -EINVAL;
2246         if (!m->sealed)
2247                 return -EPERM;
2248         if (m->n_containers <= 0)
2249                 return -EINVAL;
2250
2251         c = message_get_container(m);
2252         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2253                 uint32_t l;
2254
2255                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2256                 if (c->begin + l != m->rindex)
2257                         return -EBUSY;
2258
2259         } else {
2260                 if (c->signature && c->signature[c->index] != 0)
2261                         return -EINVAL;
2262         }
2263
2264         free(c->signature);
2265         m->n_containers--;
2266
2267         return 1;
2268 }
2269
2270 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2271         struct bus_container *c;
2272         int r;
2273
2274         if (!m)
2275                 return -EINVAL;
2276         if (!m->sealed)
2277                 return -EPERM;
2278
2279         c = message_get_container(m);
2280
2281         if (!c->signature || c->signature[c->index] == 0)
2282                 goto eof;
2283
2284         if (message_end_of_array(m, m->rindex))
2285                 goto eof;
2286
2287         if (bus_type_is_basic(c->signature[c->index])) {
2288                 if (contents)
2289                         *contents = NULL;
2290                 if (type)
2291                         *type = c->signature[c->index];
2292                 return 1;
2293         }
2294
2295         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2296
2297                 if (contents) {
2298                         size_t l;
2299                         char *sig;
2300
2301                         r = signature_element_length(c->signature+c->index+1, &l);
2302                         if (r < 0)
2303                                 return r;
2304
2305                         assert(l >= 1);
2306
2307                         sig = strndup(c->signature + c->index + 1, l);
2308                         if (!sig)
2309                                 return -ENOMEM;
2310
2311                         free(m->peeked_signature);
2312                         m->peeked_signature = sig;
2313
2314                         *contents = sig;
2315                 }
2316
2317                 if (type)
2318                         *type = SD_BUS_TYPE_ARRAY;
2319
2320                 return 1;
2321         }
2322
2323         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2324             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2325
2326                 if (contents) {
2327                         size_t l;
2328                         char *sig;
2329
2330                         r = signature_element_length(c->signature+c->index, &l);
2331                         if (r < 0)
2332                                 return r;
2333
2334                         assert(l >= 2);
2335                         sig = strndup(c->signature + c->index + 1, l - 2);
2336                         if (!sig)
2337                                 return -ENOMEM;
2338
2339                         free(m->peeked_signature);
2340                         m->peeked_signature = sig;
2341
2342                         *contents = sig;
2343                 }
2344
2345                 if (type)
2346                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2347
2348                 return 1;
2349         }
2350
2351         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2352                 if (contents) {
2353                         size_t rindex, l;
2354                         void *q;
2355
2356                         rindex = m->rindex;
2357                         r = message_peek_body(m, &rindex, 1, 1, &q);
2358                         if (r < 0)
2359                                 return r;
2360                         if (r == 0)
2361                                 goto eof;
2362
2363                         l = *(uint8_t*) q;
2364                         r = message_peek_body(m, &rindex, 1, l+1, &q);
2365                         if (r < 0)
2366                                 return r;
2367                         if (r == 0)
2368                                 return -EBADMSG;
2369
2370                         if (!validate_signature(q, l))
2371                                 return -EBADMSG;
2372
2373                         *contents = q;
2374                 }
2375
2376                 if (type)
2377                         *type = SD_BUS_TYPE_VARIANT;
2378
2379                 return 1;
2380         }
2381
2382         return -EINVAL;
2383
2384 eof:
2385         if (type)
2386                 *type = c->enclosing;
2387         if (contents)
2388                 *contents = NULL;
2389         return 0;
2390 }
2391
2392 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2393         struct bus_container *c;
2394
2395         if (!m)
2396                 return -EINVAL;
2397         if (!m->sealed)
2398                 return -EPERM;
2399
2400         if (complete) {
2401                 reset_containers(m);
2402                 m->rindex = 0;
2403                 m->root_container.index = 0;
2404
2405                 c = message_get_container(m);
2406         } else {
2407                 c = message_get_container(m);
2408
2409                 c->index = 0;
2410                 m->rindex = c->begin;
2411         }
2412
2413         return !isempty(c->signature);
2414 }
2415 static int message_read_ap(
2416                 sd_bus_message *m,
2417                 const char *types,
2418                 va_list ap) {
2419
2420         unsigned n_array, n_struct;
2421         TypeStack stack[BUS_CONTAINER_DEPTH];
2422         unsigned stack_ptr = 0;
2423         int r;
2424
2425         assert(m);
2426
2427         if (!types)
2428                 return 0;
2429
2430         /* Ideally, we'd just call ourselves recursively on every
2431          * complex type. However, the state of a va_list that is
2432          * passed to a function is undefined after that function
2433          * returns. This means we need to docode the va_list linearly
2434          * in a single stackframe. We hence implement our own
2435          * home-grown stack in an array. */
2436
2437         n_array = (unsigned) -1;
2438         n_struct = strlen(types);
2439
2440         for (;;) {
2441                 const char *t;
2442
2443                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2444                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2445                         if (r < 0)
2446                                 return r;
2447                         if (r == 0)
2448                                 break;
2449
2450                         r = sd_bus_message_exit_container(m);
2451                         if (r < 0)
2452                                 return r;
2453
2454                         continue;
2455                 }
2456
2457                 t = types;
2458                 if (n_array != (unsigned) -1)
2459                         n_array --;
2460                 else {
2461                         types ++;
2462                         n_struct--;
2463                 }
2464
2465                 switch (*t) {
2466
2467                 case SD_BUS_TYPE_BYTE:
2468                 case SD_BUS_TYPE_BOOLEAN:
2469                 case SD_BUS_TYPE_INT16:
2470                 case SD_BUS_TYPE_UINT16:
2471                 case SD_BUS_TYPE_INT32:
2472                 case SD_BUS_TYPE_UINT32:
2473                 case SD_BUS_TYPE_INT64:
2474                 case SD_BUS_TYPE_UINT64:
2475                 case SD_BUS_TYPE_DOUBLE:
2476                 case SD_BUS_TYPE_STRING:
2477                 case SD_BUS_TYPE_OBJECT_PATH:
2478                 case SD_BUS_TYPE_SIGNATURE:
2479                 case SD_BUS_TYPE_UNIX_FD: {
2480                         void *p;
2481
2482                         p = va_arg(ap, void*);
2483                         r = sd_bus_message_read_basic(m, *t, p);
2484                         if (r < 0)
2485                                 return r;
2486                         if (r == 0)
2487                                 return -ENXIO;
2488
2489                         break;
2490                 }
2491
2492                 case SD_BUS_TYPE_ARRAY: {
2493                         size_t k;
2494
2495                         r = signature_element_length(t + 1, &k);
2496                         if (r < 0)
2497                                 return r;
2498
2499                         {
2500                                 char s[k + 1];
2501                                 memcpy(s, t + 1, k);
2502                                 s[k] = 0;
2503
2504                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2505                                 if (r < 0)
2506                                         return r;
2507                                 if (r == 0)
2508                                         return -ENXIO;
2509                         }
2510
2511                         if (n_array == (unsigned) -1) {
2512                                 types += k;
2513                                 n_struct -= k;
2514                         }
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 = t + 1;
2521                         n_struct = k;
2522                         n_array = va_arg(ap, unsigned);
2523
2524                         break;
2525                 }
2526
2527                 case SD_BUS_TYPE_VARIANT: {
2528                         const char *s;
2529
2530                         s = va_arg(ap, const char *);
2531                         if (!s)
2532                                 return -EINVAL;
2533
2534                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2535                         if (r < 0)
2536                                 return r;
2537                         if (r == 0)
2538                                 return -ENXIO;
2539
2540                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2541                         if (r < 0)
2542                                 return r;
2543
2544                         types = s;
2545                         n_struct = strlen(s);
2546                         n_array = (unsigned) -1;
2547
2548                         break;
2549                 }
2550
2551                 case SD_BUS_TYPE_STRUCT_BEGIN:
2552                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2553                         size_t k;
2554
2555                         r = signature_element_length(t, &k);
2556                         if (r < 0)
2557                                 return r;
2558
2559                         {
2560                                 char s[k - 1];
2561                                 memcpy(s, t + 1, k - 2);
2562                                 s[k - 2] = 0;
2563
2564                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2565                                 if (r < 0)
2566                                         return r;
2567                                 if (r == 0)
2568                                         return -ENXIO;
2569                         }
2570
2571                         if (n_array == (unsigned) -1) {
2572                                 types += k - 1;
2573                                 n_struct -= k - 1;
2574                         }
2575
2576                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2577                         if (r < 0)
2578                                 return r;
2579
2580                         types = t + 1;
2581                         n_struct = k - 2;
2582                         n_array = (unsigned) -1;
2583
2584                         break;
2585                 }
2586
2587                 default:
2588                         return -EINVAL;
2589                 }
2590         }
2591
2592         return 1;
2593 }
2594
2595 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2596         va_list ap;
2597         int r;
2598
2599         if (!m)
2600                 return -EINVAL;
2601         if (!m->sealed)
2602                 return -EPERM;
2603         if (!types)
2604                 return -EINVAL;
2605
2606         va_start(ap, types);
2607         r = message_read_ap(m, types, ap);
2608         va_end(ap);
2609
2610         return r;
2611 }
2612
2613 static int message_peek_fields(
2614                 sd_bus_message *m,
2615                 size_t *rindex,
2616                 size_t align,
2617                 size_t nbytes,
2618                 void **ret) {
2619
2620         assert(m);
2621         assert(rindex);
2622         assert(align > 0);
2623
2624         return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2625 }
2626
2627 static int message_peek_field_uint32(
2628                 sd_bus_message *m,
2629                 size_t *ri,
2630                 uint32_t *ret) {
2631
2632         int r;
2633         void *q;
2634
2635         assert(m);
2636         assert(ri);
2637
2638         r = message_peek_fields(m, ri, 4, 4, &q);
2639         if (r < 0)
2640                 return r;
2641
2642         if (ret)
2643                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2644
2645         return 0;
2646 }
2647
2648 static int message_peek_field_string(
2649                 sd_bus_message *m,
2650                 bool (*validate)(const char *p),
2651                 size_t *ri,
2652                 const char **ret) {
2653
2654         uint32_t l;
2655         int r;
2656         void *q;
2657
2658         assert(m);
2659         assert(ri);
2660
2661         r = message_peek_field_uint32(m, ri, &l);
2662         if (r < 0)
2663                 return r;
2664
2665         r = message_peek_fields(m, ri, 1, l+1, &q);
2666         if (r < 0)
2667                 return r;
2668
2669         if (validate) {
2670                 if (!validate_nul(q, l))
2671                         return -EBADMSG;
2672
2673                 if (!validate(q))
2674                         return -EBADMSG;
2675         } else {
2676                 if (!validate_string(q, l))
2677                         return -EBADMSG;
2678         }
2679
2680         if (ret)
2681                 *ret = q;
2682
2683         return 0;
2684 }
2685
2686 static int message_peek_field_signature(
2687                 sd_bus_message *m,
2688                 size_t *ri,
2689                 const char **ret) {
2690
2691         size_t l;
2692         int r;
2693         void *q;
2694
2695         assert(m);
2696         assert(ri);
2697
2698         r = message_peek_fields(m, ri, 1, 1, &q);
2699         if (r < 0)
2700                 return r;
2701
2702         l = *(uint8_t*) q;
2703         r = message_peek_fields(m, ri, 1, l+1, &q);
2704         if (r < 0)
2705                 return r;
2706
2707         if (!validate_signature(q, l))
2708                 return -EBADMSG;
2709
2710         if (ret)
2711                 *ret = q;
2712
2713         return 0;
2714 }
2715
2716 static int message_skip_fields(
2717                 sd_bus_message *m,
2718                 size_t *ri,
2719                 uint32_t array_size,
2720                 const char **signature) {
2721
2722         size_t original_index;
2723         int r;
2724
2725         assert(m);
2726         assert(ri);
2727         assert(signature);
2728
2729         original_index = *ri;
2730
2731         for (;;) {
2732                 char t;
2733                 size_t l;
2734
2735                 if (array_size != (uint32_t) -1 &&
2736                     array_size <= *ri - original_index)
2737                         return 0;
2738
2739                 t = **signature;
2740                 if (!t)
2741                         return 0;
2742
2743                 if (t == SD_BUS_TYPE_STRING) {
2744
2745                         r = message_peek_field_string(m, NULL, ri, NULL);
2746                         if (r < 0)
2747                                 return r;
2748
2749                         (*signature)++;
2750
2751                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2752
2753                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2754                         if (r < 0)
2755                                 return r;
2756
2757                         (*signature)++;
2758
2759                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2760
2761                         r = message_peek_field_signature(m, ri, NULL);
2762                         if (r < 0)
2763                                 return r;
2764
2765                         (*signature)++;
2766
2767                 } else if (bus_type_is_basic(t)) {
2768                         ssize_t align, k;
2769
2770                         align = bus_type_get_alignment(t);
2771                         k = bus_type_get_size(t);
2772                         assert(align > 0 && k > 0);
2773
2774                         r = message_peek_fields(m, ri, align, k, NULL);
2775                         if (r < 0)
2776                                 return r;
2777
2778                         (*signature)++;
2779
2780                 } else if (t == SD_BUS_TYPE_ARRAY) {
2781
2782                         r = signature_element_length(*signature+1, &l);
2783                         if (r < 0)
2784                                 return r;
2785
2786                         assert(l >= 1);
2787                         {
2788                                 char sig[l-1], *s;
2789                                 uint32_t nas;
2790                                 int alignment;
2791
2792                                 strncpy(sig, *signature + 1, l-1);
2793                                 s = sig;
2794
2795                                 alignment = bus_type_get_alignment(sig[0]);
2796                                 if (alignment < 0)
2797                                         return alignment;
2798
2799                                 r = message_peek_field_uint32(m, ri, &nas);
2800                                 if (r < 0)
2801                                         return r;
2802                                 if (nas > BUS_ARRAY_MAX_SIZE)
2803                                         return -EBADMSG;
2804
2805                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
2806                                 if (r < 0)
2807                                         return r;
2808
2809                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
2810                                 if (r < 0)
2811                                         return r;
2812                         }
2813
2814                         (*signature) += 1 + l;
2815
2816                 } else if (t == SD_BUS_TYPE_VARIANT) {
2817                         const char *s;
2818
2819                         r = message_peek_field_signature(m, ri, &s);
2820                         if (r < 0)
2821                                 return r;
2822
2823                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2824                         if (r < 0)
2825                                 return r;
2826
2827                         (*signature)++;
2828
2829                 } else if (t == SD_BUS_TYPE_STRUCT ||
2830                            t == SD_BUS_TYPE_DICT_ENTRY) {
2831
2832                         r = signature_element_length(*signature, &l);
2833                         if (r < 0)
2834                                 return r;
2835
2836                         assert(l >= 2);
2837                         {
2838                                 char sig[l-1], *s;
2839                                 strncpy(sig, *signature + 1, l-1);
2840                                 s = sig;
2841
2842                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2843                                 if (r < 0)
2844                                         return r;
2845                         }
2846
2847                         *signature += l;
2848                 } else
2849                         return -EINVAL;
2850         }
2851 }
2852
2853 int bus_message_parse_fields(sd_bus_message *m) {
2854         size_t ri;
2855         int r;
2856         uint32_t unix_fds = 0;
2857
2858         assert(m);
2859
2860         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2861                 const char *signature;
2862                 uint8_t *header;
2863
2864                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2865                 if (r < 0)
2866                         return r;
2867
2868                 r = message_peek_field_signature(m, &ri, &signature);
2869                 if (r < 0)
2870                         return r;
2871
2872                 switch (*header) {
2873                 case _SD_BUS_MESSAGE_HEADER_INVALID:
2874                         return -EBADMSG;
2875
2876                 case SD_BUS_MESSAGE_HEADER_PATH:
2877
2878                         if (m->path)
2879                                 return -EBADMSG;
2880
2881                         if (!streq(signature, "o"))
2882                                 return -EBADMSG;
2883
2884                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2885                         break;
2886
2887                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2888
2889                         if (m->interface)
2890                                 return -EBADMSG;
2891
2892                         if (!streq(signature, "s"))
2893                                 return -EBADMSG;
2894
2895                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2896                         break;
2897
2898                 case SD_BUS_MESSAGE_HEADER_MEMBER:
2899
2900                         if (m->member)
2901                                 return -EBADMSG;
2902
2903                         if (!streq(signature, "s"))
2904                                 return -EBADMSG;
2905
2906                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2907                         break;
2908
2909                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2910
2911                         if (m->error.name)
2912                                 return -EBADMSG;
2913
2914                         if (!streq(signature, "s"))
2915                                 return -EBADMSG;
2916
2917                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2918                         break;
2919
2920                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2921
2922                         if (m->destination)
2923                                 return -EBADMSG;
2924
2925                         if (!streq(signature, "s"))
2926                                 return -EBADMSG;
2927
2928                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2929                         break;
2930
2931                 case SD_BUS_MESSAGE_HEADER_SENDER:
2932
2933                         if (m->sender)
2934                                 return -EBADMSG;
2935
2936                         if (!streq(signature, "s"))
2937                                 return -EBADMSG;
2938
2939                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2940                         break;
2941
2942
2943                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2944                         const char *s;
2945                         char *c;
2946
2947                         if (m->root_container.signature)
2948                                 return -EBADMSG;
2949
2950                         if (!streq(signature, "g"))
2951                                 return -EBADMSG;
2952
2953                         r = message_peek_field_signature(m, &ri, &s);
2954                         if (r < 0)
2955                                 return r;
2956
2957                         c = strdup(s);
2958                         if (!c)
2959                                 return -ENOMEM;
2960
2961                         free(m->root_container.signature);
2962                         m->root_container.signature = c;
2963                         break;
2964                 }
2965
2966                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2967                         if (m->reply_serial != 0)
2968                                 return -EBADMSG;
2969
2970                         if (!streq(signature, "u"))
2971                                 return -EBADMSG;
2972
2973                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2974                         if (r < 0)
2975                                 return r;
2976
2977                         if (m->reply_serial == 0)
2978                                 return -EBADMSG;
2979
2980                         break;
2981
2982                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2983                         if (unix_fds != 0)
2984                                 return -EBADMSG;
2985
2986                         if (!streq(signature, "u"))
2987                                 return -EBADMSG;
2988
2989                         r = message_peek_field_uint32(m, &ri, &unix_fds);
2990                         if (r < 0)
2991                                 return -EBADMSG;
2992
2993                         if (unix_fds == 0)
2994                                 return -EBADMSG;
2995
2996                         break;
2997
2998                 default:
2999                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3000                 }
3001
3002                 if (r < 0)
3003                         return r;
3004         }
3005
3006         if (m->n_fds != unix_fds)
3007                 return -EBADMSG;
3008
3009         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3010                 return -EBADMSG;
3011
3012         switch (m->header->type) {
3013
3014         case SD_BUS_MESSAGE_TYPE_SIGNAL:
3015                 if (!m->path || !m->interface || !m->member)
3016                         return -EBADMSG;
3017                 break;
3018
3019         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3020
3021                 if (!m->path || !m->member)
3022                         return -EBADMSG;
3023
3024                 break;
3025
3026         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3027
3028                 if (m->reply_serial == 0)
3029                         return -EBADMSG;
3030                 break;
3031
3032         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3033
3034                 if (m->reply_serial == 0 || !m->error.name)
3035                         return -EBADMSG;
3036                 break;
3037         }
3038
3039         /* Try to read the error message, but if we can't it's a non-issue */
3040         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3041                 sd_bus_message_read(m, "s", &m->error.message);
3042
3043         return 0;
3044 }
3045
3046 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3047         int r;
3048         size_t l, a;
3049
3050         assert(m);
3051
3052         if (m->sealed)
3053                 return -EPERM;
3054
3055         if (m->n_containers > 0)
3056                 return -EBADMSG;
3057
3058         /* If there's a non-trivial signature set, then add it in here */
3059         if (!isempty(m->root_container.signature)) {
3060                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3061                 if (r < 0)
3062                         return r;
3063         }
3064
3065         if (m->n_fds > 0) {
3066                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3067                 if (r < 0)
3068                         return r;
3069         }
3070
3071         l = BUS_MESSAGE_FIELDS_SIZE(m);
3072         a = ALIGN8(l) - l;
3073
3074         if (a > 0) {
3075                 /* Add padding at the end, since we know the body
3076                  * needs to start at an 8 byte alignment. */
3077                 void *p;
3078
3079                 p = message_extend_fields(m, 1, a);
3080                 if (!p)
3081                         return -ENOMEM;
3082
3083                 memset(p, 0, a);
3084                 m->header->fields_size -= a;
3085         }
3086
3087         m->header->serial = serial;
3088         m->sealed = true;
3089
3090         return 0;
3091 }
3092
3093 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3094         if (!m)
3095                 return -EINVAL;
3096         if (!destination)
3097                 return -EINVAL;
3098         if (m->sealed)
3099                 return -EPERM;
3100         if (m->destination)
3101                 return -EEXIST;
3102
3103         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3104 }
3105
3106 int bus_message_dump(sd_bus_message *m) {
3107         const char *u = NULL, *uu = NULL, *s = NULL;
3108         char **cmdline = NULL;
3109         unsigned level = 1;
3110         int r;
3111         uid_t owner, audit_loginuid;
3112         uint32_t audit_sessionid;
3113
3114         assert(m);
3115
3116         printf("Message %p\n"
3117                "\tn_ref=%u\n"
3118                "\tendian=%c\n"
3119                "\ttype=%i\n"
3120                "\tflags=%u\n"
3121                "\tversion=%u\n"
3122                "\tserial=%u\n"
3123                "\tfields_size=%u\n"
3124                "\tbody_size=%u\n"
3125                "\tpath=%s\n"
3126                "\tinterface=%s\n"
3127                "\tmember=%s\n"
3128                "\tdestination=%s\n"
3129                "\tsender=%s\n"
3130                "\tsignature=%s\n"
3131                "\treply_serial=%u\n"
3132                "\terror.name=%s\n"
3133                "\terror.message=%s\n"
3134                "\tsealed=%s\n",
3135                m,
3136                m->n_ref,
3137                m->header->endian,
3138                m->header->type,
3139                m->header->flags,
3140                m->header->version,
3141                BUS_MESSAGE_SERIAL(m),
3142                BUS_MESSAGE_FIELDS_SIZE(m),
3143                BUS_MESSAGE_BODY_SIZE(m),
3144                strna(m->path),
3145                strna(m->interface),
3146                strna(m->member),
3147                strna(m->destination),
3148                strna(m->sender),
3149                strna(m->root_container.signature),
3150                m->reply_serial,
3151                strna(m->error.name),
3152                strna(m->error.message),
3153                yes_no(m->sealed));
3154
3155         if (m->pid != 0)
3156                 printf("\tpid=%lu\n", (unsigned long) m->pid);
3157         if (m->tid != 0)
3158                 printf("\ttid=%lu\n", (unsigned long) m->tid);
3159         if (m->uid_valid)
3160                 printf("\tuid=%lu\n", (unsigned long) m->uid);
3161         if (m->gid_valid)
3162                 printf("\tgid=%lu\n", (unsigned long) m->gid);
3163         if (m->pid_starttime != 0)
3164                 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3165         if (m->monotonic != 0)
3166                 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3167         if (m->realtime != 0)
3168                 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3169         if (m->exe)
3170                 printf("\texe=[%s]\n", m->exe);
3171         if (m->comm)
3172                 printf("\tcomm=[%s]\n", m->comm);
3173         if (m->tid_comm)
3174                 printf("\ttid_comm=[%s]\n", m->tid_comm);
3175         if (m->label)
3176                 printf("\tlabel=[%s]\n", m->label);
3177         if (m->cgroup)
3178                 printf("\tcgroup=[%s]\n", m->cgroup);
3179
3180         sd_bus_message_get_unit(m, &u);
3181         if (u)
3182                 printf("\tunit=[%s]\n", u);
3183         sd_bus_message_get_user_unit(m, &uu);
3184         if (uu)
3185                 printf("\tuser_unit=[%s]\n", uu);
3186         sd_bus_message_get_session(m, &s);
3187         if (s)
3188                 printf("\tsession=[%s]\n", s);
3189         if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3190                 printf("\towner_uid=%lu\n", (unsigned long) owner);
3191         if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3192                 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3193         if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3194                 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3195
3196         if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3197                 char **c;
3198
3199                 fputs("\tcmdline=[", stdout);
3200                 STRV_FOREACH(c, cmdline) {
3201                         if (c != cmdline)
3202                                 putchar(' ');
3203
3204                         fputs(*c, stdout);
3205                 }
3206
3207                 fputs("]\n", stdout);
3208         }
3209
3210         r = sd_bus_message_rewind(m, true);
3211         if (r < 0) {
3212                 log_error("Failed to rewind: %s", strerror(-r));
3213                 return r;
3214         }
3215
3216         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3217
3218         for(;;) {
3219                 _cleanup_free_ char *prefix = NULL;
3220                 const char *contents = NULL;
3221                 char type;
3222                 union {
3223                         uint8_t u8;
3224                         uint16_t u16;
3225                         int16_t s16;
3226                         uint32_t u32;
3227                         int32_t s32;
3228                         uint64_t u64;
3229                         int64_t s64;
3230                         double d64;
3231                         const char *string;
3232                         int i;
3233                 } basic;
3234
3235                 r = sd_bus_message_peek_type(m, &type, &contents);
3236                 if (r < 0) {
3237                         log_error("Failed to peek type: %s", strerror(-r));
3238                         return r;
3239                 }
3240                 if (r == 0) {
3241                         if (level <= 1)
3242                                 break;
3243
3244                         r = sd_bus_message_exit_container(m);
3245                         if (r < 0) {
3246                                 log_error("Failed to exit container: %s", strerror(-r));
3247                                 return r;
3248                         }
3249
3250                         level--;
3251
3252                         prefix = strrep("\t", level);
3253                         if (!prefix)
3254                                 return log_oom();
3255
3256                         if (type == SD_BUS_TYPE_ARRAY)
3257                                 printf("%s} END_ARRAY \n", prefix);
3258                         else if (type == SD_BUS_TYPE_VARIANT)
3259                                 printf("%s} END_VARIANT\n", prefix);
3260                         else if (type == SD_BUS_TYPE_STRUCT)
3261                                 printf("%s} END_STRUCT\n", prefix);
3262                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3263                                 printf("%s} END_DICT_ENTRY\n", prefix);
3264
3265                         continue;
3266                 }
3267
3268                 prefix = strrep("\t", level);
3269                 if (!prefix)
3270                         return log_oom();
3271
3272                 if (bus_type_is_container(type) > 0) {
3273                         r = sd_bus_message_enter_container(m, type, contents);
3274                         if (r < 0) {
3275                                 log_error("Failed to enter container: %s", strerror(-r));
3276                                 return r;
3277                         }
3278
3279                         if (type == SD_BUS_TYPE_ARRAY)
3280                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3281                         else if (type == SD_BUS_TYPE_VARIANT)
3282                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3283                         else if (type == SD_BUS_TYPE_STRUCT)
3284                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3285                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3286                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3287
3288                         level ++;
3289
3290                         continue;
3291                 }
3292
3293                 r = sd_bus_message_read_basic(m, type, &basic);
3294                 if (r < 0) {
3295                         log_error("Failed to get basic: %s", strerror(-r));
3296                         return r;
3297                 }
3298
3299                 switch (type) {
3300
3301                 case SD_BUS_TYPE_BYTE:
3302                         printf("%sBYTE: %u\n", prefix, basic.u8);
3303                         break;
3304
3305                 case SD_BUS_TYPE_BOOLEAN:
3306                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3307                         break;
3308
3309                 case SD_BUS_TYPE_INT16:
3310                         printf("%sINT16: %i\n", prefix, basic.s16);
3311                         break;
3312
3313                 case SD_BUS_TYPE_UINT16:
3314                         printf("%sUINT16: %u\n", prefix, basic.u16);
3315                         break;
3316
3317                 case SD_BUS_TYPE_INT32:
3318                         printf("%sINT32: %i\n", prefix, basic.s32);
3319                         break;
3320
3321                 case SD_BUS_TYPE_UINT32:
3322                         printf("%sUINT32: %u\n", prefix, basic.u32);
3323                         break;
3324
3325                 case SD_BUS_TYPE_INT64:
3326                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3327                         break;
3328
3329                 case SD_BUS_TYPE_UINT64:
3330                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3331                         break;
3332
3333                 case SD_BUS_TYPE_DOUBLE:
3334                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
3335                         break;
3336
3337                 case SD_BUS_TYPE_STRING:
3338                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3339                         break;
3340
3341                 case SD_BUS_TYPE_OBJECT_PATH:
3342                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3343                         break;
3344
3345                 case SD_BUS_TYPE_SIGNATURE:
3346                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3347                         break;
3348
3349                 case SD_BUS_TYPE_UNIX_FD:
3350                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
3351                         break;
3352
3353                 default:
3354                         assert_not_reached("Unknown basic type.");
3355                 }
3356         }
3357
3358         printf("} END_MESSAGE\n");
3359         return 0;
3360 }
3361
3362 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3363         size_t total;
3364         void *p, *e;
3365
3366         assert(m);
3367         assert(buffer);
3368         assert(sz);
3369
3370         total = BUS_MESSAGE_SIZE(m);
3371
3372         p = malloc(total);
3373         if (!p)
3374                 return -ENOMEM;
3375
3376         e = mempcpy(p, m->header, sizeof(*m->header));
3377
3378         if (m->fields) {
3379                 e = mempcpy(e, m->fields, m->header->fields_size);
3380
3381                 if (m->header->fields_size % 8 != 0)
3382                         e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3383         }
3384
3385         if (m->body)
3386                 e = mempcpy(e, m->body, m->header->body_size);
3387
3388         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3389
3390         *buffer = p;
3391         *sz = total;
3392
3393         return 0;
3394 }
3395
3396 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3397         int r;
3398
3399         assert(m);
3400         assert(l);
3401
3402         r = sd_bus_message_enter_container(m, 'a', "s");
3403         if (r < 0)
3404                 return r;
3405
3406         for (;;) {
3407                 const char *s;
3408
3409                 r = sd_bus_message_read_basic(m, 's', &s);
3410                 if (r < 0)
3411                         return r;
3412                 if (r == 0)
3413                         break;
3414
3415                 r = strv_extend(l, s);
3416                 if (r < 0)
3417                         return r;
3418         }
3419
3420         r = sd_bus_message_exit_container(m);
3421         if (r < 0)
3422                 return r;
3423
3424         return 0;
3425 }
3426
3427 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3428         int r;
3429         const char *t = NULL;
3430         unsigned j;
3431
3432         assert(m);
3433
3434         r = sd_bus_message_rewind(m, true);
3435         if (r < 0)
3436                 return NULL;
3437
3438         for (j = 0; j <= i; j++) {
3439                 char type;
3440
3441                 r = sd_bus_message_peek_type(m, &type, NULL);
3442                 if (r < 0)
3443                         return NULL;
3444
3445                 if (type != SD_BUS_TYPE_STRING &&
3446                     type != SD_BUS_TYPE_OBJECT_PATH &&
3447                     type != SD_BUS_TYPE_SIGNATURE)
3448                         return NULL;
3449
3450                 r = sd_bus_message_read_basic(m, type, &t);
3451                 if (r < 0)
3452                         return NULL;
3453         }
3454
3455         return t;
3456 }
3457
3458 int bus_header_size(struct bus_header *h, size_t *sum) {
3459         size_t fs, bs;
3460
3461         assert(h);
3462         assert(sum);
3463
3464         if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3465                 fs = h->fields_size;
3466                 bs = h->body_size;
3467         } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3468                 fs = bswap_32(h->fields_size);
3469                 bs = bswap_32(h->body_size);
3470         } else
3471                 return -EBADMSG;
3472
3473         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
3474         return 0;
3475 }