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