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