chiark / gitweb /
Revert "libsystemd-bus: use assert_return"
[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 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "cgroup-util.h"
31
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-type.h"
36 #include "bus-signature.h"
37 #include "bus-gvariant.h"
38
39 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40
41 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
42
43         if (p == NULL)
44                 return NULL;
45
46         if (old_base == new_base)
47                 return (void*) p;
48
49         if ((uint8_t*) p < (uint8_t*) old_base)
50                 return (void*) p;
51
52         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
53                 return (void*) p;
54
55         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
56 }
57
58 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
59         assert(m);
60         assert(part);
61
62         if (part->memfd >= 0) {
63                 /* If we can reuse the memfd, try that. For that it
64                  * can't be sealed yet. */
65
66                 if (!part->sealed)
67                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
68                 else {
69                         if (part->mapped > 0)
70                                 assert_se(munmap(part->data, part->mapped) == 0);
71
72                         close_nointr_nofail(part->memfd);
73                 }
74
75         } else if (part->munmap_this)
76                 munmap(part->data, part->mapped);
77         else if (part->free_this)
78                 free(part->data);
79
80         if (part != &m->body)
81                 free(part);
82 }
83
84 static void message_reset_parts(sd_bus_message *m) {
85         struct bus_body_part *part;
86
87         assert(m);
88
89         part = &m->body;
90         while (m->n_body_parts > 0) {
91                 struct bus_body_part *next = part->next;
92                 message_free_part(m, part);
93                 part = next;
94                 m->n_body_parts--;
95         }
96
97         m->body_end = NULL;
98
99         m->cached_rindex_part = NULL;
100         m->cached_rindex_part_begin = 0;
101 }
102
103 static void message_reset_containers(sd_bus_message *m) {
104         unsigned i;
105
106         assert(m);
107
108         for (i = 0; i < m->n_containers; i++) {
109                 free(m->containers[i].signature);
110                 free(m->containers[i].offsets);
111         }
112
113         free(m->containers);
114         m->containers = NULL;
115
116         m->n_containers = 0;
117         m->root_container.index = 0;
118 }
119
120 static void message_free(sd_bus_message *m) {
121         assert(m);
122
123         if (m->free_header)
124                 free(m->header);
125
126         message_reset_parts(m);
127
128         if (m->free_kdbus)
129                 free(m->kdbus);
130
131         if (m->release_kdbus) {
132                 uint64_t off;
133
134                 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
135                 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
136         }
137
138         if (m->bus)
139                 sd_bus_unref(m->bus);
140
141         if (m->free_fds) {
142                 close_many(m->fds, m->n_fds);
143                 free(m->fds);
144         }
145
146         if (m->iovec != m->iovec_fixed)
147                 free(m->iovec);
148
149         message_reset_containers(m);
150         free(m->root_container.signature);
151         free(m->root_container.offsets);
152
153         free(m->peeked_signature);
154
155         bus_creds_done(&m->creds);
156         free(m);
157 }
158
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
160         void *op, *np;
161         size_t old_size, new_size, start;
162
163         assert(m);
164
165         if (m->poisoned)
166                 return NULL;
167
168         old_size = sizeof(struct bus_header) + m->header->fields_size;
169         start = ALIGN_TO(old_size, align);
170         new_size = start + sz;
171
172         if (old_size == new_size)
173                 return (uint8_t*) m->header + old_size;
174
175         if (new_size > (size_t) ((uint32_t) -1))
176                 goto poison;
177
178         if (m->free_header) {
179                 np = realloc(m->header, ALIGN8(new_size));
180                 if (!np)
181                         goto poison;
182         } else {
183                 /* Initially, the header is allocated as part of of
184                  * the sd_bus_message itself, let's replace it by
185                  * dynamic data */
186
187                 np = malloc(ALIGN8(new_size));
188                 if (!np)
189                         goto poison;
190
191                 memcpy(np, m->header, sizeof(struct bus_header));
192         }
193
194         /* Zero out padding */
195         if (start > old_size)
196                 memset((uint8_t*) np + old_size, 0, start - old_size);
197
198         op = m->header;
199         m->header = np;
200         m->header->fields_size = new_size - sizeof(struct bus_header);
201
202         /* Adjust quick access pointers */
203         m->path = adjust_pointer(m->path, op, old_size, m->header);
204         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205         m->member = adjust_pointer(m->member, op, old_size, m->header);
206         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
209
210         m->free_header = true;
211
212         if (add_offset) {
213                 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
214                         goto poison;
215
216                 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
217         }
218
219         return (uint8_t*) np + start;
220
221 poison:
222         m->poisoned = true;
223         return NULL;
224 }
225
226 static int message_append_field_string(
227                 sd_bus_message *m,
228                 uint8_t h,
229                 char type,
230                 const char *s,
231                 const char **ret) {
232
233         size_t l;
234         uint8_t *p;
235
236         assert(m);
237
238         /* dbus1 doesn't allow strings over 32bit, let's enforce this
239          * globally, to not risk convertability */
240         l = strlen(s);
241         if (l > (size_t) (uint32_t) -1)
242                 return -EINVAL;
243
244         /* Signature "(yv)" where the variant contains "s" */
245
246         if (BUS_MESSAGE_IS_GVARIANT(m)) {
247
248                 /* (field id byte + 7x padding, ((string + NUL) + NUL + signature string 's') */
249                 p = message_extend_fields(m, 8, 1 + 7 + l + 1 + 1 + 1, true);
250                 if (!p)
251                         return -ENOMEM;
252
253                 p[0] = h;
254                 memset(p+1, 0, 7);
255                 memcpy(p+8, s, l);
256                 p[8+l] = 0;
257                 p[8+l+1] = 0;
258                 p[8+l+2] = type;
259
260                 if (ret)
261                         *ret = (char*) p + 8;
262
263         } else {
264                 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
265                 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
266                 if (!p)
267                         return -ENOMEM;
268
269                 p[0] = h;
270                 p[1] = 1;
271                 p[2] = type;
272                 p[3] = 0;
273
274                 ((uint32_t*) p)[1] = l;
275                 memcpy(p + 8, s, l + 1);
276
277                 if (ret)
278                         *ret = (char*) p + 8;
279         }
280
281         return 0;
282 }
283
284 static int message_append_field_signature(
285                 sd_bus_message *m,
286                 uint8_t h,
287                 const char *s,
288                 const char **ret) {
289
290         size_t l;
291         uint8_t *p;
292
293         assert(m);
294
295         /* dbus1 doesn't allow signatures over 32bit, let's enforce
296          * this globally, to not risk convertability */
297         l = strlen(s);
298         if (l > 255)
299                 return -EINVAL;
300
301         /* Signature "(yv)" where the variant contains "g" */
302
303         if (BUS_MESSAGE_IS_GVARIANT(m))
304                 /* For gvariant the serialization is the same as for normal strings */
305                 return message_append_field_string(m, h, 'g', s, ret);
306         else {
307                 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
308                 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
309                 if (!p)
310                         return -ENOMEM;
311
312                 p[0] = h;
313                 p[1] = 1;
314                 p[2] = SD_BUS_TYPE_SIGNATURE;
315                 p[3] = 0;
316                 p[4] = l;
317                 memcpy(p + 5, s, l + 1);
318
319                 if (ret)
320                         *ret = (const char*) p + 5;
321         }
322
323         return 0;
324 }
325
326 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
327         uint8_t *p;
328
329         assert(m);
330
331         if (BUS_MESSAGE_IS_GVARIANT(m)) {
332                 /* (field id byte + 7x padding + ((value + NUL + signature string 'u') */
333
334                 p = message_extend_fields(m, 8, 1 + 7 + 4 + 1 + 1, true);
335                 if (!p)
336                         return -ENOMEM;
337
338                 p[0] = h;
339                 memset(p+1, 0, 7);
340                 *((uint32_t*) (p + 8)) = x;
341                 p[12] = 0;
342                 p[13] = 'u';
343         } else {
344                 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
345                 p = message_extend_fields(m, 8, 4 + 4, false);
346                 if (!p)
347                         return -ENOMEM;
348
349                 p[0] = h;
350                 p[1] = 1;
351                 p[2] = SD_BUS_TYPE_UINT32;
352                 p[3] = 0;
353
354                 ((uint32_t*) p)[1] = x;
355         }
356
357         return 0;
358 }
359
360 int bus_message_from_header(
361                 sd_bus *bus,
362                 void *buffer,
363                 size_t length,
364                 int *fds,
365                 unsigned n_fds,
366                 const struct ucred *ucred,
367                 const char *label,
368                 size_t extra,
369                 sd_bus_message **ret) {
370
371         sd_bus_message *m;
372         struct bus_header *h;
373         size_t a, label_sz;
374
375         assert(buffer || length <= 0);
376         assert(fds || n_fds <= 0);
377         assert(ret);
378
379         if (length < sizeof(struct bus_header))
380                 return -EBADMSG;
381
382         h = buffer;
383         if (h->version != 1 &&
384             h->version != 2)
385                 return -EBADMSG;
386
387         if (h->serial == 0)
388                 return -EBADMSG;
389
390         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
391                 return -EBADMSG;
392
393         if (h->endian != BUS_LITTLE_ENDIAN &&
394             h->endian != BUS_BIG_ENDIAN)
395                 return -EBADMSG;
396
397         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
398
399         if (label) {
400                 label_sz = strlen(label);
401                 a += label_sz + 1;
402         }
403
404         m = malloc0(a);
405         if (!m)
406                 return -ENOMEM;
407
408         m->n_ref = 1;
409         m->sealed = true;
410         m->header = h;
411         m->fds = fds;
412         m->n_fds = n_fds;
413
414         if (ucred) {
415                 m->creds.uid = ucred->uid;
416                 m->creds.pid = ucred->pid;
417                 m->creds.gid = ucred->gid;
418                 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
419         }
420
421         if (label) {
422                 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
423                 memcpy(m->creds.label, label, label_sz + 1);
424
425                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
426         }
427
428         if (bus)
429                 m->bus = sd_bus_ref(bus);
430
431         *ret = m;
432         return 0;
433 }
434
435 int bus_message_from_malloc(
436                 sd_bus *bus,
437                 void *buffer,
438                 size_t length,
439                 int *fds,
440                 unsigned n_fds,
441                 const struct ucred *ucred,
442                 const char *label,
443                 sd_bus_message **ret) {
444
445         sd_bus_message *m;
446         size_t sz;
447         int r;
448
449         r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
450         if (r < 0)
451                 return r;
452
453         if (length != BUS_MESSAGE_SIZE(m)) {
454                 r = -EBADMSG;
455                 goto fail;
456         }
457
458         sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
459         if (sz > 0) {
460                 m->n_body_parts = 1;
461                 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
462                 m->body.size = sz;
463                 m->body.sealed = true;
464                 m->body.memfd = -1;
465         }
466
467         m->n_iovec = 1;
468         m->iovec = m->iovec_fixed;
469         m->iovec[0].iov_base = buffer;
470         m->iovec[0].iov_len = length;
471
472         r = bus_message_parse_fields(m);
473         if (r < 0)
474                 goto fail;
475
476         /* We take possession of the memory and fds now */
477         m->free_header = true;
478         m->free_fds = true;
479
480         *ret = m;
481         return 0;
482
483 fail:
484         message_free(m);
485         return r;
486 }
487
488 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
489         sd_bus_message *m;
490
491         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
492         if (!m)
493                 return NULL;
494
495         m->n_ref = 1;
496         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
497         m->header->endian = BUS_NATIVE_ENDIAN;
498         m->header->type = type;
499         m->header->version = bus ? bus->message_version : 1;
500         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
501         m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
502
503         if (bus)
504                 m->bus = sd_bus_ref(bus);
505
506         return m;
507 }
508
509 _public_ int sd_bus_message_new_signal(
510                 sd_bus *bus,
511                 const char *path,
512                 const char *interface,
513                 const char *member,
514                 sd_bus_message **m) {
515
516         sd_bus_message *t;
517         int r;
518
519         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
520         assert_return(object_path_is_valid(path), -EINVAL);
521         assert_return(interface_name_is_valid(interface), -EINVAL);
522         assert_return(member_name_is_valid(member), -EINVAL);
523         assert_return(m, -EINVAL);
524
525         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
526         if (!t)
527                 return -ENOMEM;
528
529         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
530
531         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
532         if (r < 0)
533                 goto fail;
534         r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
535         if (r < 0)
536                 goto fail;
537         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
538         if (r < 0)
539                 goto fail;
540
541         *m = t;
542         return 0;
543
544 fail:
545         sd_bus_message_unref(t);
546         return r;
547 }
548
549 _public_ int sd_bus_message_new_method_call(
550                 sd_bus *bus,
551                 const char *destination,
552                 const char *path,
553                 const char *interface,
554                 const char *member,
555                 sd_bus_message **m) {
556
557         sd_bus_message *t;
558         int r;
559
560         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
561         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
562         assert_return(object_path_is_valid(path), -EINVAL);
563         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
564         assert_return(member_name_is_valid(member), -EINVAL);
565         assert_return(m, -EINVAL);
566
567         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
568         if (!t)
569                 return -ENOMEM;
570
571         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
572         if (r < 0)
573                 goto fail;
574         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
575         if (r < 0)
576                 goto fail;
577
578         if (interface) {
579                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
580                 if (r < 0)
581                         goto fail;
582         }
583
584         if (destination) {
585                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
586                 if (r < 0)
587                         goto fail;
588         }
589
590         *m = t;
591         return 0;
592
593 fail:
594         message_free(t);
595         return r;
596 }
597
598 static int message_new_reply(
599                 sd_bus_message *call,
600                 uint8_t type,
601                 sd_bus_message **m) {
602
603         sd_bus_message *t;
604         int r;
605
606         assert_return(call, -EINVAL);
607         assert_return(call->sealed, -EPERM);
608         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
609         assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
610         assert_return(m, -EINVAL);
611
612         t = message_new(call->bus, type);
613         if (!t)
614                 return -ENOMEM;
615
616         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
617         t->reply_serial = BUS_MESSAGE_SERIAL(call);
618
619         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
620         if (r < 0)
621                 goto fail;
622
623         if (call->sender) {
624                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
625                 if (r < 0)
626                         goto fail;
627         }
628
629         t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
630         t->enforced_reply_signature = call->enforced_reply_signature;
631
632         *m = t;
633         return 0;
634
635 fail:
636         message_free(t);
637         return r;
638 }
639
640 _public_ int sd_bus_message_new_method_return(
641                 sd_bus_message *call,
642                 sd_bus_message **m) {
643
644         return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
645 }
646
647 _public_ int sd_bus_message_new_method_error(
648                 sd_bus_message *call,
649                 const sd_bus_error *e,
650                 sd_bus_message **m) {
651
652         sd_bus_message *t;
653         int r;
654
655         assert_return(sd_bus_error_is_set(e), -EINVAL);
656         assert_return(m, -EINVAL);
657
658         r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
659         if (r < 0)
660                 return r;
661
662         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
663         if (r < 0)
664                 goto fail;
665
666         if (e->message) {
667                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
668                 if (r < 0)
669                         goto fail;
670         }
671
672         t->error._need_free = -1;
673
674         *m = t;
675         return 0;
676
677 fail:
678         message_free(t);
679         return r;
680 }
681
682 _public_ int sd_bus_message_new_method_errorf(
683                 sd_bus_message *call,
684                 sd_bus_message **m,
685                 const char *name,
686                 const char *format,
687                 ...) {
688
689         _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
690         va_list ap;
691
692         assert_return(name, -EINVAL);
693         assert_return(m, -EINVAL);
694
695         va_start(ap, format);
696         bus_error_setfv(&error, name, format, ap);
697         va_end(ap);
698
699         return sd_bus_message_new_method_error(call, &error, m);
700 }
701
702 _public_ int sd_bus_message_new_method_errno(
703                 sd_bus_message *call,
704                 int error,
705                 const sd_bus_error *p,
706                 sd_bus_message **m) {
707
708         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
709
710         if (sd_bus_error_is_set(p))
711                 return sd_bus_message_new_method_error(call, p, m);
712
713         sd_bus_error_set_errno(&berror, error);
714
715         return sd_bus_message_new_method_error(call, &berror, m);
716 }
717
718 _public_ int sd_bus_message_new_method_errnof(
719                 sd_bus_message *call,
720                 sd_bus_message **m,
721                 int error,
722                 const char *format,
723                 ...) {
724
725         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
726         va_list ap;
727
728         va_start(ap, format);
729         bus_error_set_errnofv(&berror, error, format, ap);
730         va_end(ap);
731
732         return sd_bus_message_new_method_error(call, &berror, m);
733 }
734
735 int bus_message_new_synthetic_error(
736                 sd_bus *bus,
737                 uint64_t serial,
738                 const sd_bus_error *e,
739                 sd_bus_message **m) {
740
741         sd_bus_message *t;
742         int r;
743
744         assert(sd_bus_error_is_set(e));
745         assert(m);
746
747         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
748         if (!t)
749                 return -ENOMEM;
750
751         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
752         t->reply_serial = serial;
753
754         r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
755         if (r < 0)
756                 goto fail;
757
758         if (bus && bus->unique_name) {
759                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
760                 if (r < 0)
761                         goto fail;
762         }
763
764         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
765         if (r < 0)
766                 goto fail;
767
768         if (e->message) {
769                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
770                 if (r < 0)
771                         goto fail;
772         }
773
774         t->error._need_free = -1;
775
776         *m = t;
777         return 0;
778
779 fail:
780         message_free(t);
781         return r;
782 }
783
784 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
785         assert_return(m, NULL);
786
787         assert(m->n_ref > 0);
788         m->n_ref++;
789
790         return m;
791 }
792
793 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
794         assert_return(m, NULL);
795
796         assert(m->n_ref > 0);
797         m->n_ref--;
798
799         if (m->n_ref <= 0)
800                 message_free(m);
801
802         return NULL;
803 }
804
805 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
806         assert_return(m, -EINVAL);
807         assert_return(type, -EINVAL);
808
809         *type = m->header->type;
810         return 0;
811 }
812
813 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
814         assert_return(m, -EINVAL);
815         assert_return(serial, -EINVAL);
816         assert_return(m->header->serial != 0, -ENOENT);
817
818         *serial = BUS_MESSAGE_SERIAL(m);
819         return 0;
820 }
821
822 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
823         assert_return(m, -EINVAL);
824         assert_return(serial, -EINVAL);
825         assert_return(m->reply_serial != 0, -ENOENT);
826
827         *serial = m->reply_serial;
828         return 0;
829 }
830
831 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
832         assert_return(m, -EINVAL);
833
834         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
835 }
836
837 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
838         assert_return(m, -EINVAL);
839
840         return !!(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
841 }
842
843 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
844         assert_return(m, NULL);
845
846         return m->path;
847 }
848
849 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
850         assert_return(m, NULL);
851
852         return m->interface;
853 }
854
855 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
856         assert_return(m, NULL);
857
858         return m->member;
859 }
860
861 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
862         assert_return(m, NULL);
863
864         return m->destination;
865 }
866
867 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
868         assert_return(m, NULL);
869
870         return m->sender;
871 }
872
873 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
874         assert_return(m, NULL);
875         assert_return(sd_bus_error_is_set(&m->error), NULL);
876
877         return &m->error;
878 }
879
880 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
881         assert_return(m, -EINVAL);
882         assert_return(usec, -EINVAL);
883         assert_return(m->monotonic > 0, -ENODATA);
884
885         *usec = m->monotonic;
886         return 0;
887 }
888
889 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
890         assert_return(m, -EINVAL);
891         assert_return(usec, -EINVAL);
892         assert_return(m->realtime > 0, -ENODATA);
893
894         *usec = m->realtime;
895         return 0;
896 }
897
898 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
899         assert_return(m, NULL);
900
901         if (m->creds.mask == 0)
902                 return NULL;
903
904         return &m->creds;
905 }
906
907 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
908                                       const char *interface,
909                                       const char *member) {
910         assert_return(m, -EINVAL);
911
912         if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
913                 return 0;
914
915         if (interface && (!m->interface || !streq(m->interface, interface)))
916                 return 0;
917
918         if (member &&  (!m->member || !streq(m->member, member)))
919                 return 0;
920
921         return 1;
922 }
923
924 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
925                                            const char *interface,
926                                            const char *member) {
927         assert_return(m, -EINVAL);
928
929         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
930                 return 0;
931
932         if (interface && (!m->interface || !streq(m->interface, interface)))
933                 return 0;
934
935         if (member &&  (!m->member || !streq(m->member, member)))
936                 return 0;
937
938         return 1;
939 }
940
941 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
942         assert_return(m, -EINVAL);
943
944         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
945                 return 0;
946
947         if (name && (!m->error.name || !streq(m->error.name, name)))
948                 return 0;
949
950         return 1;
951 }
952
953 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
954         assert_return(m, -EINVAL);
955         assert_return(!m->sealed, -EPERM);
956         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
957
958         if (b)
959                 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
960         else
961                 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
962
963         return 0;
964 }
965
966 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
967         assert_return(m, -EINVAL);
968         assert_return(!m->sealed, -EPERM);
969
970         if (b)
971                 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
972         else
973                 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
974
975         return 0;
976 }
977
978 static struct bus_container *message_get_container(sd_bus_message *m) {
979         assert(m);
980
981         if (m->n_containers == 0)
982                 return &m->root_container;
983
984         assert(m->containers);
985         return m->containers + m->n_containers - 1;
986 }
987
988 struct bus_body_part *message_append_part(sd_bus_message *m) {
989         struct bus_body_part *part;
990
991         assert(m);
992
993         if (m->poisoned)
994                 return NULL;
995
996         if (m->n_body_parts <= 0) {
997                 part = &m->body;
998                 zero(*part);
999         } else {
1000                 assert(m->body_end);
1001
1002                 part = new0(struct bus_body_part, 1);
1003                 if (!part) {
1004                         m->poisoned = true;
1005                         return NULL;
1006                 }
1007
1008                 m->body_end->next = part;
1009         }
1010
1011         part->memfd = -1;
1012         m->body_end = part;
1013         m->n_body_parts ++;
1014
1015         return part;
1016 }
1017
1018 static void part_zero(struct bus_body_part *part, size_t sz) {
1019         assert(part);
1020         assert(sz > 0);
1021         assert(sz < 8);
1022
1023         /* All other fields can be left in their defaults */
1024         assert(!part->data);
1025         assert(part->memfd < 0);
1026
1027         part->size = sz;
1028         part->is_zero = true;
1029         part->sealed = true;
1030 }
1031
1032 static int part_make_space(
1033                 struct sd_bus_message *m,
1034                 struct bus_body_part *part,
1035                 size_t sz,
1036                 void **q) {
1037
1038         void *n;
1039         int r;
1040
1041         assert(m);
1042         assert(part);
1043         assert(!part->sealed);
1044
1045         if (m->poisoned)
1046                 return -ENOMEM;
1047
1048         if (!part->data && part->memfd < 0)
1049                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1050
1051         if (part->memfd >= 0) {
1052                 uint64_t u = sz;
1053
1054                 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1055                 if (r < 0) {
1056                         m->poisoned = true;
1057                         return -errno;
1058                 }
1059
1060                 if (!part->data || sz > part->mapped) {
1061                         size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1062
1063                         if (part->mapped <= 0)
1064                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1065                         else
1066                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1067
1068                         if (n == MAP_FAILED) {
1069                                 m->poisoned = true;
1070                                 return -errno;
1071                         }
1072
1073                         part->mapped = psz;
1074                         part->data = n;
1075                 }
1076
1077                 part->munmap_this = true;
1078         } else {
1079                 n = realloc(part->data, MAX(sz, 1u));
1080                 if (!n) {
1081                         m->poisoned = true;
1082                         return -ENOMEM;
1083                 }
1084
1085                 part->data = n;
1086                 part->free_this = true;
1087         }
1088
1089         if (q)
1090                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1091
1092         part->size = sz;
1093         return 0;
1094 }
1095
1096 static int message_add_offset(sd_bus_message *m, size_t offset) {
1097         struct bus_container *c;
1098
1099         assert(m);
1100         assert(BUS_MESSAGE_IS_GVARIANT(m));
1101
1102         /* Add offset to current container, unless this is the first
1103          * item in it, which will have the 0 offset, which we can
1104          * ignore. */
1105         c = message_get_container(m);
1106
1107         if (!c->need_offsets)
1108                 return 0;
1109
1110         if (!GREEDY_REALLOC(c->offsets, c->n_offsets_allocated, c->n_offsets + 1))
1111                 return -ENOMEM;
1112
1113         c->offsets[c->n_offsets++] = offset;
1114         return 0;
1115 }
1116
1117 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1118         struct bus_container *c;
1119
1120         assert(m);
1121
1122         if (expand <= 0)
1123                 return;
1124
1125         /* Update counters */
1126         for (c = m->containers; c < m->containers + m->n_containers; c++) {
1127
1128                 if (c->array_size)
1129                         *c->array_size += expand;
1130         }
1131 }
1132
1133 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1134         size_t start_body, end_body, padding, added;
1135         void *p;
1136         int r;
1137
1138         assert(m);
1139         assert(align > 0);
1140         assert(!m->sealed);
1141
1142         if (m->poisoned)
1143                 return NULL;
1144
1145         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1146         end_body = start_body + sz;
1147
1148         padding = start_body - m->header->body_size;
1149         added = padding + sz;
1150
1151         /* Check for 32bit overflows */
1152         if (end_body > (size_t) ((uint32_t) -1)) {
1153                 m->poisoned = true;
1154                 return NULL;
1155         }
1156
1157         if (added > 0) {
1158                 struct bus_body_part *part = NULL;
1159                 bool add_new_part;
1160
1161                 add_new_part =
1162                         m->n_body_parts <= 0 ||
1163                         m->body_end->sealed ||
1164                         padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1165
1166                 if (add_new_part) {
1167                         if (padding > 0) {
1168                                 part = message_append_part(m);
1169                                 if (!part)
1170                                         return NULL;
1171
1172                                 part_zero(part, padding);
1173                         }
1174
1175                         part = message_append_part(m);
1176                         if (!part)
1177                                 return NULL;
1178
1179                         r = part_make_space(m, part, sz, &p);
1180                         if (r < 0)
1181                                 return NULL;
1182                 } else {
1183                         struct bus_container *c;
1184                         void *op;
1185                         size_t os, start_part, end_part;
1186
1187                         part = m->body_end;
1188                         op = part->data;
1189                         os = part->size;
1190
1191                         start_part = ALIGN_TO(part->size, align);
1192                         end_part = start_part + sz;
1193
1194                         r = part_make_space(m, part, end_part, &p);
1195                         if (r < 0)
1196                                 return NULL;
1197
1198                         if (padding > 0) {
1199                                 memset(p, 0, padding);
1200                                 p = (uint8_t*) p + padding;
1201                         }
1202
1203                         /* Readjust pointers */
1204                         for (c = m->containers; c < m->containers + m->n_containers; c++)
1205                                 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1206
1207                         m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1208                 }
1209         } else
1210                 /* Return something that is not NULL and is aligned */
1211                 p = (uint8_t *) NULL + align;
1212
1213         m->header->body_size = end_body;
1214         message_extend_containers(m, added);
1215
1216         if (add_offset) {
1217                 r = message_add_offset(m, end_body);
1218                 if (r < 0) {
1219                         m->poisoned = true;
1220                         return NULL;
1221                 }
1222         }
1223
1224         return p;
1225 }
1226
1227 static int message_push_fd(sd_bus_message *m, int fd) {
1228         int *f, copy;
1229
1230         assert(m);
1231
1232         if (fd < 0)
1233                 return -EINVAL;
1234
1235         if (!m->allow_fds)
1236                 return -ENOTSUP;
1237
1238         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1239         if (copy < 0)
1240                 return -errno;
1241
1242         f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1243         if (!f) {
1244                 m->poisoned = true;
1245                 close_nointr_nofail(copy);
1246                 return -ENOMEM;
1247         }
1248
1249         m->fds = f;
1250         m->fds[m->n_fds] = copy;
1251         m->free_fds = true;
1252
1253         return copy;
1254 }
1255
1256 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1257         _cleanup_close_ int fd = -1;
1258         struct bus_container *c;
1259         ssize_t align, sz;
1260         void *a;
1261
1262         assert_return(m, -EINVAL);
1263         assert_return(!m->sealed, -EPERM);
1264         assert_return(bus_type_is_basic(type), -EINVAL);
1265         assert_return(!m->poisoned, -ESTALE);
1266
1267         c = message_get_container(m);
1268
1269         if (c->signature && c->signature[c->index]) {
1270                 /* Container signature is already set */
1271
1272                 if (c->signature[c->index] != type)
1273                         return -ENXIO;
1274         } else {
1275                 char *e;
1276
1277                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1278                 if (c->enclosing != 0)
1279                         return -ENXIO;
1280
1281                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1282                 if (!e) {
1283                         m->poisoned = true;
1284                         return -ENOMEM;
1285                 }
1286         }
1287
1288         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1289                 uint8_t u8;
1290                 uint32_t u32;
1291
1292                 switch (type) {
1293
1294                 case SD_BUS_TYPE_SIGNATURE:
1295                 case SD_BUS_TYPE_STRING:
1296                         p = strempty(p);
1297
1298                         /* Fall through... */
1299                 case SD_BUS_TYPE_OBJECT_PATH:
1300                         if (!p)
1301                                 return -EINVAL;
1302
1303                         align = 1;
1304                         sz = strlen(p) + 1;
1305                         break;
1306
1307                 case SD_BUS_TYPE_BOOLEAN:
1308
1309                         u8 = p && *(int*) p;
1310                         p = &u8;
1311
1312                         align = sz = 1;
1313                         break;
1314
1315                 case SD_BUS_TYPE_UNIX_FD:
1316
1317                         if (!p)
1318                                 return -EINVAL;
1319
1320                         fd = message_push_fd(m, *(int*) p);
1321                         if (fd < 0)
1322                                 return fd;
1323
1324                         u32 = m->n_fds;
1325                         p = &u32;
1326
1327                         align = sz = 4;
1328                         break;
1329
1330                 default:
1331                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1332                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1333                         break;
1334                 }
1335
1336                 assert(align > 0);
1337                 assert(sz > 0);
1338
1339                 a = message_extend_body(m, align, sz, true);
1340                 if (!a)
1341                         return -ENOMEM;
1342
1343                 memcpy(a, p, sz);
1344
1345                 if (stored)
1346                         *stored = (const uint8_t*) a;
1347
1348         } else {
1349                 uint32_t u32;
1350
1351                 switch (type) {
1352
1353                 case SD_BUS_TYPE_STRING:
1354                         /* To make things easy we'll serialize a NULL string
1355                          * into the empty string */
1356                         p = strempty(p);
1357
1358                         /* Fall through... */
1359                 case SD_BUS_TYPE_OBJECT_PATH:
1360
1361                         if (!p)
1362                                 return -EINVAL;
1363
1364                         align = 4;
1365                         sz = 4 + strlen(p) + 1;
1366                         break;
1367
1368                 case SD_BUS_TYPE_SIGNATURE:
1369
1370                         p = strempty(p);
1371
1372                         align = 1;
1373                         sz = 1 + strlen(p) + 1;
1374                         break;
1375
1376                 case SD_BUS_TYPE_BOOLEAN:
1377
1378                         u32 = p && *(int*) p;
1379                         p = &u32;
1380
1381                         align = sz = 4;
1382                         break;
1383
1384                 case SD_BUS_TYPE_UNIX_FD:
1385
1386                         if (!p)
1387                                 return -EINVAL;
1388
1389                         fd = message_push_fd(m, *(int*) p);
1390                         if (fd < 0)
1391                                 return fd;
1392
1393                         u32 = m->n_fds;
1394                         p = &u32;
1395
1396                         align = sz = 4;
1397                         break;
1398
1399                 default:
1400                         align = bus_type_get_alignment(type);
1401                         sz = bus_type_get_size(type);
1402                         break;
1403                 }
1404
1405                 assert(align > 0);
1406                 assert(sz > 0);
1407
1408                 a = message_extend_body(m, align, sz, false);
1409                 if (!a)
1410                         return -ENOMEM;
1411
1412                 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1413                         *(uint32_t*) a = sz - 5;
1414                         memcpy((uint8_t*) a + 4, p, sz - 4);
1415
1416                         if (stored)
1417                                 *stored = (const uint8_t*) a + 4;
1418
1419                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1420                         *(uint8_t*) a = sz - 1;
1421                         memcpy((uint8_t*) a + 1, p, sz - 1);
1422
1423                         if (stored)
1424                                 *stored = (const uint8_t*) a + 1;
1425                 } else {
1426                         memcpy(a, p, sz);
1427
1428                         if (stored)
1429                                 *stored = a;
1430                 }
1431         }
1432
1433         if (type == SD_BUS_TYPE_UNIX_FD)
1434                 m->n_fds ++;
1435
1436         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1437                 c->index++;
1438
1439         fd = -1;
1440         return 0;
1441 }
1442
1443 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1444         return message_append_basic(m, type, p, NULL);
1445 }
1446
1447 _public_ int sd_bus_message_append_string_space(
1448                 sd_bus_message *m,
1449                 size_t size,
1450                 char **s) {
1451
1452         struct bus_container *c;
1453         void *a;
1454
1455         assert_return(m, -EINVAL);
1456         assert_return(s, -EINVAL);
1457         assert_return(!m->sealed, -EPERM);
1458         assert_return(!m->poisoned, -ESTALE);
1459
1460         c = message_get_container(m);
1461
1462         if (c->signature && c->signature[c->index]) {
1463                 /* Container signature is already set */
1464
1465                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1466                         return -ENXIO;
1467         } else {
1468                 char *e;
1469
1470                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1471                 if (c->enclosing != 0)
1472                         return -ENXIO;
1473
1474                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1475                 if (!e) {
1476                         m->poisoned = true;
1477                         return -ENOMEM;
1478                 }
1479         }
1480
1481         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1482                 a = message_extend_body(m, 1, size + 1, true);
1483                 if (!a)
1484                         return -ENOMEM;
1485
1486                 *s = a;
1487         } else {
1488                 a = message_extend_body(m, 4, 4 + size + 1, false);
1489                 if (!a)
1490                         return -ENOMEM;
1491
1492                 *(uint32_t*) a = size;
1493                 *s = (char*) a + 4;
1494         }
1495
1496         (*s)[size] = 0;
1497
1498         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1499                 c->index++;
1500
1501         return 0;
1502 }
1503
1504 _public_ int sd_bus_message_append_string_iovec(
1505                 sd_bus_message *m,
1506                 const struct iovec *iov,
1507                 unsigned n) {
1508
1509         size_t size;
1510         unsigned i;
1511         char *p;
1512         int r;
1513
1514         assert_return(m, -EINVAL);
1515         assert_return(!m->sealed, -EPERM);
1516         assert_return(iov || n == 0, -EINVAL);
1517         assert_return(!m->poisoned, -ESTALE);
1518
1519         size = IOVEC_TOTAL_SIZE(iov, n);
1520
1521         r = sd_bus_message_append_string_space(m, size, &p);
1522         if (r < 0)
1523                 return r;
1524
1525         for (i = 0; i < n; i++) {
1526
1527                 if (iov[i].iov_base)
1528                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
1529                 else
1530                         memset(p, ' ', iov[i].iov_len);
1531
1532                 p += iov[i].iov_len;
1533         }
1534
1535         return 0;
1536 }
1537
1538 static int bus_message_open_array(
1539                 sd_bus_message *m,
1540                 struct bus_container *c,
1541                 const char *contents,
1542                 uint32_t **array_size,
1543                 size_t *begin,
1544                 bool *need_offsets) {
1545
1546         unsigned nindex;
1547         int alignment, r;
1548
1549         assert(m);
1550         assert(c);
1551         assert(contents);
1552         assert(array_size);
1553         assert(begin);
1554         assert(need_offsets);
1555
1556         if (!signature_is_single(contents, true))
1557                 return -EINVAL;
1558
1559         if (c->signature && c->signature[c->index]) {
1560
1561                 /* Verify the existing signature */
1562
1563                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1564                         return -ENXIO;
1565
1566                 if (!startswith(c->signature + c->index + 1, contents))
1567                         return -ENXIO;
1568
1569                 nindex = c->index + 1 + strlen(contents);
1570         } else {
1571                 char *e;
1572
1573                 if (c->enclosing != 0)
1574                         return -ENXIO;
1575
1576                 /* Extend the existing signature */
1577
1578                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1579                 if (!e) {
1580                         m->poisoned = true;
1581                         return -ENOMEM;
1582                 }
1583
1584                 nindex = e - c->signature;
1585         }
1586
1587         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1588                 alignment = bus_gvariant_get_alignment(contents);
1589                 if (alignment < 0)
1590                         return alignment;
1591
1592                 /* Add alignment padding and add to offset list */
1593                 if (!message_extend_body(m, alignment, 0, false))
1594                         return -ENOMEM;
1595
1596                 r = bus_gvariant_is_fixed_size(contents);
1597                 if (r < 0)
1598                         return r;
1599
1600                 *begin = m->header->body_size;
1601                 *need_offsets = r == 0;
1602         } else {
1603                 void *a, *op;
1604                 size_t os;
1605                 struct bus_body_part *o;
1606
1607                 alignment = bus_type_get_alignment(contents[0]);
1608                 if (alignment < 0)
1609                         return alignment;
1610
1611                 a = message_extend_body(m, 4, 4, false);
1612                 if (!a)
1613                         return -ENOMEM;
1614
1615                 o = m->body_end;
1616                 op = m->body_end->data;
1617                 os = m->body_end->size;
1618
1619                 /* Add alignment between size and first element */
1620                 if (!message_extend_body(m, alignment, 0, false))
1621                         return -ENOMEM;
1622
1623                 /* location of array size might have changed so let's readjust a */
1624                 if (o == m->body_end)
1625                         a = adjust_pointer(a, op, os, m->body_end->data);
1626
1627                 *(uint32_t*) a = 0;
1628                 *array_size = a;
1629         }
1630
1631         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1632                 c->index = nindex;
1633
1634         return 0;
1635 }
1636
1637 static int bus_message_open_variant(
1638                 sd_bus_message *m,
1639                 struct bus_container *c,
1640                 const char *contents) {
1641
1642         assert(m);
1643         assert(c);
1644         assert(contents);
1645
1646         if (!signature_is_single(contents, false))
1647                 return -EINVAL;
1648
1649         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1650                 return -EINVAL;
1651
1652         if (c->signature && c->signature[c->index]) {
1653
1654                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1655                         return -ENXIO;
1656
1657         } else {
1658                 char *e;
1659
1660                 if (c->enclosing != 0)
1661                         return -ENXIO;
1662
1663                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1664                 if (!e) {
1665                         m->poisoned = true;
1666                         return -ENOMEM;
1667                 }
1668         }
1669
1670         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1671                 /* Variants are always aligned to 8 */
1672
1673                 if (!message_extend_body(m, 8, 0, false))
1674                         return -ENOMEM;
1675
1676         } else {
1677                 size_t l;
1678                 void *a;
1679
1680                 l = strlen(contents);
1681                 a = message_extend_body(m, 1, 1 + l + 1, false);
1682                 if (!a)
1683                         return -ENOMEM;
1684
1685                 *(uint8_t*) a = l;
1686                 memcpy((uint8_t*) a + 1, contents, l + 1);
1687         }
1688
1689         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1690                 c->index++;
1691
1692         return 0;
1693 }
1694
1695 static int bus_message_open_struct(
1696                 sd_bus_message *m,
1697                 struct bus_container *c,
1698                 const char *contents,
1699                 size_t *begin,
1700                 bool *need_offsets) {
1701
1702         size_t nindex;
1703         int r;
1704
1705         assert(m);
1706         assert(c);
1707         assert(contents);
1708         assert(begin);
1709         assert(need_offsets);
1710
1711         if (!signature_is_valid(contents, false))
1712                 return -EINVAL;
1713
1714         if (c->signature && c->signature[c->index]) {
1715                 size_t l;
1716
1717                 l = strlen(contents);
1718
1719                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1720                     !startswith(c->signature + c->index + 1, contents) ||
1721                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1722                         return -ENXIO;
1723
1724                 nindex = c->index + 1 + l + 1;
1725         } else {
1726                 char *e;
1727
1728                 if (c->enclosing != 0)
1729                         return -ENXIO;
1730
1731                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1732                 if (!e) {
1733                         m->poisoned = true;
1734                         return -ENOMEM;
1735                 }
1736
1737                 nindex = e - c->signature;
1738         }
1739
1740         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1741                 int alignment;
1742
1743                 alignment = bus_gvariant_get_alignment(contents);
1744                 if (alignment < 0)
1745                         return alignment;
1746
1747                 if (!message_extend_body(m, alignment, 0, false))
1748                         return -ENOMEM;
1749
1750                 r = bus_gvariant_is_fixed_size(contents);
1751                 if (r < 0)
1752                         return r;
1753
1754                 *begin = m->header->body_size;
1755                 *need_offsets = r == 0;
1756         } else {
1757                 /* Align contents to 8 byte boundary */
1758                 if (!message_extend_body(m, 8, 0, false))
1759                         return -ENOMEM;
1760         }
1761
1762         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1763                 c->index = nindex;
1764
1765         return 0;
1766 }
1767
1768 static int bus_message_open_dict_entry(
1769                 sd_bus_message *m,
1770                 struct bus_container *c,
1771                 const char *contents,
1772                 size_t *begin,
1773                 bool *need_offsets) {
1774
1775         int r;
1776
1777         assert(m);
1778         assert(c);
1779         assert(contents);
1780         assert(begin);
1781         assert(need_offsets);
1782
1783         if (!signature_is_pair(contents))
1784                 return -EINVAL;
1785
1786         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1787                 return -ENXIO;
1788
1789         if (c->signature && c->signature[c->index]) {
1790                 size_t l;
1791
1792                 l = strlen(contents);
1793
1794                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1795                     !startswith(c->signature + c->index + 1, contents) ||
1796                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1797                         return -ENXIO;
1798         } else
1799                 return -ENXIO;
1800
1801         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1802                 int alignment;
1803
1804                 alignment = bus_gvariant_get_alignment(contents);
1805                 if (alignment < 0)
1806                         return alignment;
1807
1808                 if (!message_extend_body(m, alignment, 0, false))
1809                         return -ENOMEM;
1810
1811                 r = bus_gvariant_is_fixed_size(contents);
1812                 if (r < 0)
1813                         return r;
1814
1815                 *begin = m->header->body_size;
1816                 *need_offsets = r == 0;
1817         } else {
1818                 /* Align contents to 8 byte boundary */
1819                 if (!message_extend_body(m, 8, 0, false))
1820                         return -ENOMEM;
1821         }
1822
1823         return 0;
1824 }
1825
1826 _public_ int sd_bus_message_open_container(
1827                 sd_bus_message *m,
1828                 char type,
1829                 const char *contents) {
1830
1831         struct bus_container *c, *w;
1832         uint32_t *array_size = NULL;
1833         char *signature;
1834         size_t before, begin;
1835         bool need_offsets = false;
1836         int r;
1837
1838         assert_return(m, -EINVAL);
1839         assert_return(!m->sealed, -EPERM);
1840         assert_return(contents, -EINVAL);
1841         assert_return(!m->poisoned, -ESTALE);
1842
1843         /* Make sure we have space for one more container */
1844         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1845         if (!w) {
1846                 m->poisoned = true;
1847                 return -ENOMEM;
1848         }
1849
1850         m->containers = w;
1851
1852         c = message_get_container(m);
1853
1854         signature = strdup(contents);
1855         if (!signature) {
1856                 m->poisoned = true;
1857                 return -ENOMEM;
1858         }
1859
1860         /* Save old index in the parent container, in case we have to
1861          * abort this container */
1862         c->saved_index = c->index;
1863         before = m->header->body_size;
1864
1865         if (type == SD_BUS_TYPE_ARRAY)
1866                 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1867         else if (type == SD_BUS_TYPE_VARIANT)
1868                 r = bus_message_open_variant(m, c, contents);
1869         else if (type == SD_BUS_TYPE_STRUCT)
1870                 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1871         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1872                 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1873         else
1874                 r = -EINVAL;
1875
1876         if (r < 0) {
1877                 free(signature);
1878                 return r;
1879         }
1880
1881         /* OK, let's fill it in */
1882         w += m->n_containers++;
1883         w->enclosing = type;
1884         w->signature = signature;
1885         w->index = 0;
1886         w->array_size = array_size;
1887         w->before = before;
1888         w->begin = begin;
1889         w->n_offsets = w->n_offsets_allocated = 0;
1890         w->offsets = NULL;
1891         w->need_offsets = need_offsets;
1892
1893         return 0;
1894 }
1895
1896 static size_t determine_word_size(size_t sz, size_t extra) {
1897         if (sz + extra <= 0xFF)
1898                 return 1;
1899         else if (sz + extra*2 <= 0xFFFF)
1900                 return 2;
1901         else if (sz + extra*4 <= 0xFFFFFFFF)
1902                 return 4;
1903         else
1904                 return 8;
1905 }
1906
1907 static size_t read_word_le(void *p, size_t sz) {
1908         union {
1909                 uint16_t u16;
1910                 uint32_t u32;
1911                 uint64_t u64;
1912         } x;
1913
1914         assert(p);
1915
1916         if (sz == 1)
1917                 return *(uint8_t*) p;
1918
1919         memcpy(&x, p, sz);
1920
1921         if (sz == 2)
1922                 return le16toh(x.u16);
1923         else if (sz == 4)
1924                 return le32toh(x.u32);
1925         else if (sz == 4)
1926                 return le64toh(x.u64);
1927
1928         assert_not_reached("unknown word width");
1929 }
1930
1931 static void write_word_le(void *p, size_t sz, size_t value) {
1932         union {
1933                 uint16_t u16;
1934                 uint32_t u32;
1935                 uint64_t u64;
1936         } x;
1937
1938         assert(p);
1939         assert(sz == 8 || (value < (1ULL << (sz*8))));
1940
1941         if (sz == 1) {
1942                 *(uint8_t*) p = value;
1943                 return;
1944         } else if (sz == 2)
1945                 x.u16 = htole16((uint16_t) value);
1946         else if (sz == 4)
1947                 x.u32 = htole32((uint32_t) value);
1948         else if (sz == 8)
1949                 x.u64 = htole64((uint64_t) value);
1950         else
1951                 assert_not_reached("unknown word width");
1952
1953         memcpy(p, &x, sz);
1954 }
1955
1956 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
1957
1958         assert(m);
1959         assert(c);
1960
1961         if (!BUS_MESSAGE_IS_GVARIANT(m))
1962                 return 0;
1963
1964         if (c->need_offsets) {
1965                 size_t payload, sz, i;
1966                 uint8_t *a;
1967
1968                 /* Variable-width arrays */
1969
1970                 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
1971                 sz = determine_word_size(payload, c->n_offsets);
1972
1973                 a = message_extend_body(m, 1, sz * c->n_offsets, true);
1974                 if (!a)
1975                         return -ENOMEM;
1976
1977                 for (i = 0; i < c->n_offsets; i++)
1978                         write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
1979         } else {
1980                 void *a;
1981
1982                 /* Fixed-width or empty arrays */
1983
1984                 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
1985                 if (!a)
1986                         return -ENOMEM;
1987         }
1988
1989         return 0;
1990 }
1991
1992 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
1993         uint8_t *a;
1994         size_t l;
1995
1996         assert(m);
1997         assert(c);
1998
1999         if (!BUS_MESSAGE_IS_GVARIANT(m))
2000                 return 0;
2001
2002         l = strlen(c->signature);
2003
2004         a = message_extend_body(m, 1, 1 + l, true);
2005         if (!a)
2006                 return -ENOMEM;
2007
2008         a[0] = 0;
2009         memcpy(a+1, c->signature, l);
2010
2011         return 0;
2012 }
2013
2014 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2015         size_t n_variable = 0;
2016         unsigned i = 0;
2017         const char *p;
2018         uint8_t *a;
2019         int r;
2020
2021         assert(m);
2022         assert(c);
2023
2024         if (!BUS_MESSAGE_IS_GVARIANT(m))
2025                 return 0;
2026
2027         p = strempty(c->signature);
2028         while (*p != 0) {
2029                 size_t n;
2030
2031                 r = signature_element_length(p, &n);
2032                 if (r < 0)
2033                         return r;
2034                 else {
2035                         char t[n+1];
2036
2037                         memcpy(t, p, n);
2038                         t[n] = 0;
2039
2040                         r = bus_gvariant_is_fixed_size(t);
2041                         if (r < 0)
2042                                 return r;
2043                 }
2044
2045                 assert(i <= c->n_offsets);
2046
2047                 /* We need to add an offset for each item that has a
2048                  * variable size and that is not the last one in the
2049                  * list */
2050                 if (r == 0 && p[n] != 0)
2051                         n_variable++;
2052
2053                 i++;
2054                 p += n;
2055         }
2056
2057         assert(i == c->n_offsets);
2058
2059         if (n_variable <= 0) {
2060                 a = message_extend_body(m, 1, 0, add_offset);
2061                 if (!a)
2062                         return -ENOMEM;
2063         } else {
2064                 size_t sz;
2065                 unsigned j;
2066
2067                 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2068
2069                 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2070
2071                 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2072                 if (!a)
2073                         return -ENOMEM;
2074
2075                 p = strempty(c->signature);
2076                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2077                         unsigned k;
2078                         size_t n;
2079
2080                         r = signature_element_length(p, &n);
2081                         if (r < 0)
2082                                 return r;
2083                         else {
2084                                 char t[n+1];
2085
2086                                 memcpy(t, p, n);
2087                                 t[n] = 0;
2088
2089                                 p += n;
2090
2091                                 r = bus_gvariant_is_fixed_size(t);
2092                                 if (r < 0)
2093                                         return r;
2094                                 if (r > 0 || p[0] == 0)
2095                                         continue;
2096                         }
2097
2098                         k = n_variable - 1 - j;
2099
2100                         write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2101
2102                         j++;
2103                 }
2104         }
2105
2106         return 0;
2107 }
2108
2109 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2110         struct bus_container *c;
2111         int r;
2112
2113         assert_return(m, -EINVAL);
2114         assert_return(!m->sealed, -EPERM);
2115         assert_return(m->n_containers > 0, -EINVAL);
2116         assert_return(!m->poisoned, -ESTALE);
2117
2118         c = message_get_container(m);
2119
2120         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2121                 if (c->signature && c->signature[c->index] != 0)
2122                         return -EINVAL;
2123
2124         m->n_containers--;
2125
2126         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2127                 r = bus_message_close_array(m, c);
2128         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2129                 r = bus_message_close_variant(m, c);
2130         else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2131                 r = bus_message_close_struct(m, c, true);
2132         else
2133                 assert_not_reached("Unknown container type");
2134
2135         free(c->signature);
2136         free(c->offsets);
2137
2138         return r;
2139 }
2140
2141 typedef struct {
2142         const char *types;
2143         unsigned n_struct;
2144         unsigned n_array;
2145 } TypeStack;
2146
2147 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2148         assert(stack);
2149         assert(max > 0);
2150
2151         if (*i >= max)
2152                 return -EINVAL;
2153
2154         stack[*i].types = types;
2155         stack[*i].n_struct = n_struct;
2156         stack[*i].n_array = n_array;
2157         (*i)++;
2158
2159         return 0;
2160 }
2161
2162 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2163         assert(stack);
2164         assert(max > 0);
2165         assert(types);
2166         assert(n_struct);
2167         assert(n_array);
2168
2169         if (*i <= 0)
2170                 return 0;
2171
2172         (*i)--;
2173         *types = stack[*i].types;
2174         *n_struct = stack[*i].n_struct;
2175         *n_array = stack[*i].n_array;
2176
2177         return 1;
2178 }
2179
2180 int bus_message_append_ap(
2181                 sd_bus_message *m,
2182                 const char *types,
2183                 va_list ap) {
2184
2185         unsigned n_array, n_struct;
2186         TypeStack stack[BUS_CONTAINER_DEPTH];
2187         unsigned stack_ptr = 0;
2188         int r;
2189
2190         assert(m);
2191
2192         if (!types)
2193                 return 0;
2194
2195         n_array = (unsigned) -1;
2196         n_struct = strlen(types);
2197
2198         for (;;) {
2199                 const char *t;
2200
2201                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2202                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2203                         if (r < 0)
2204                                 return r;
2205                         if (r == 0)
2206                                 break;
2207
2208                         r = sd_bus_message_close_container(m);
2209                         if (r < 0)
2210                                 return r;
2211
2212                         continue;
2213                 }
2214
2215                 t = types;
2216                 if (n_array != (unsigned) -1)
2217                         n_array --;
2218                 else {
2219                         types ++;
2220                         n_struct--;
2221                 }
2222
2223                 switch (*t) {
2224
2225                 case SD_BUS_TYPE_BYTE: {
2226                         uint8_t x;
2227
2228                         x = (uint8_t) va_arg(ap, int);
2229                         r = sd_bus_message_append_basic(m, *t, &x);
2230                         break;
2231                 }
2232
2233                 case SD_BUS_TYPE_BOOLEAN:
2234                 case SD_BUS_TYPE_INT32:
2235                 case SD_BUS_TYPE_UINT32:
2236                 case SD_BUS_TYPE_UNIX_FD: {
2237                         uint32_t x;
2238
2239                         /* We assume a boolean is the same as int32_t */
2240                         assert_cc(sizeof(int32_t) == sizeof(int));
2241
2242                         x = va_arg(ap, uint32_t);
2243                         r = sd_bus_message_append_basic(m, *t, &x);
2244                         break;
2245                 }
2246
2247                 case SD_BUS_TYPE_INT16:
2248                 case SD_BUS_TYPE_UINT16: {
2249                         uint16_t x;
2250
2251                         x = (uint16_t) va_arg(ap, int);
2252                         r = sd_bus_message_append_basic(m, *t, &x);
2253                         break;
2254                 }
2255
2256                 case SD_BUS_TYPE_INT64:
2257                 case SD_BUS_TYPE_UINT64:
2258                 case SD_BUS_TYPE_DOUBLE: {
2259                         uint64_t x;
2260
2261                         x = va_arg(ap, uint64_t);
2262                         r = sd_bus_message_append_basic(m, *t, &x);
2263                         break;
2264                 }
2265
2266                 case SD_BUS_TYPE_STRING:
2267                 case SD_BUS_TYPE_OBJECT_PATH:
2268                 case SD_BUS_TYPE_SIGNATURE: {
2269                         const char *x;
2270
2271                         x = va_arg(ap, const char*);
2272                         r = sd_bus_message_append_basic(m, *t, x);
2273                         break;
2274                 }
2275
2276                 case SD_BUS_TYPE_ARRAY: {
2277                         size_t k;
2278
2279                         r = signature_element_length(t + 1, &k);
2280                         if (r < 0)
2281                                 return r;
2282
2283                         {
2284                                 char s[k + 1];
2285                                 memcpy(s, t + 1, k);
2286                                 s[k] = 0;
2287
2288                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2289                                 if (r < 0)
2290                                         return r;
2291                         }
2292
2293                         if (n_array == (unsigned) -1) {
2294                                 types += k;
2295                                 n_struct -= k;
2296                         }
2297
2298                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2299                         if (r < 0)
2300                                 return r;
2301
2302                         types = t + 1;
2303                         n_struct = k;
2304                         n_array = va_arg(ap, unsigned);
2305
2306                         break;
2307                 }
2308
2309                 case SD_BUS_TYPE_VARIANT: {
2310                         const char *s;
2311
2312                         s = va_arg(ap, const char*);
2313                         if (!s)
2314                                 return -EINVAL;
2315
2316                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2317                         if (r < 0)
2318                                 return r;
2319
2320                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2321                         if (r < 0)
2322                                 return r;
2323
2324                         types = s;
2325                         n_struct = strlen(s);
2326                         n_array = (unsigned) -1;
2327
2328                         break;
2329                 }
2330
2331                 case SD_BUS_TYPE_STRUCT_BEGIN:
2332                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2333                         size_t k;
2334
2335                         r = signature_element_length(t, &k);
2336                         if (r < 0)
2337                                 return r;
2338
2339                         {
2340                                 char s[k - 1];
2341
2342                                 memcpy(s, t + 1, k - 2);
2343                                 s[k - 2] = 0;
2344
2345                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2346                                 if (r < 0)
2347                                         return r;
2348                         }
2349
2350                         if (n_array == (unsigned) -1) {
2351                                 types += k - 1;
2352                                 n_struct -= k - 1;
2353                         }
2354
2355                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2356                         if (r < 0)
2357                                 return r;
2358
2359                         types = t + 1;
2360                         n_struct = k - 2;
2361                         n_array = (unsigned) -1;
2362
2363                         break;
2364                 }
2365
2366                 default:
2367                         r = -EINVAL;
2368                 }
2369
2370                 if (r < 0)
2371                         return r;
2372         }
2373
2374         return 1;
2375 }
2376
2377 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2378         va_list ap;
2379         int r;
2380
2381         assert_return(m, -EINVAL);
2382         assert_return(types, -EINVAL);
2383         assert_return(!m->sealed, -EPERM);
2384         assert_return(!m->poisoned, -ESTALE);
2385
2386         va_start(ap, types);
2387         r = bus_message_append_ap(m, types, ap);
2388         va_end(ap);
2389
2390         return r;
2391 }
2392
2393 _public_ int sd_bus_message_append_array_space(
2394                 sd_bus_message *m,
2395                 char type,
2396                 size_t size,
2397                 void **ptr) {
2398
2399         ssize_t align, sz;
2400         void *a;
2401         int r;
2402
2403         assert_return(m, -EINVAL);
2404         assert_return(!m->sealed, -EPERM);
2405         assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2406         assert_return(ptr || size == 0, -EINVAL);
2407         assert_return(!m->poisoned, -ESTALE);
2408
2409         /* alignment and size of the trivial types (except bool) is
2410          * identical for gvariant and dbus1 marshalling */
2411         align = bus_type_get_alignment(type);
2412         sz = bus_type_get_size(type);
2413
2414         assert_se(align > 0);
2415         assert_se(sz > 0);
2416
2417         if (size % sz != 0)
2418                 return -EINVAL;
2419
2420         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2421         if (r < 0)
2422                 return r;
2423
2424         a = message_extend_body(m, align, size, false);
2425         if (!a)
2426                 return -ENOMEM;
2427
2428         r = sd_bus_message_close_container(m);
2429         if (r < 0)
2430                 return r;
2431
2432         *ptr = a;
2433         return 0;
2434 }
2435
2436 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2437                                          char type,
2438                                          const void *ptr,
2439                                          size_t size) {
2440         int r;
2441         void *p;
2442
2443         assert_return(m, -EINVAL);
2444         assert_return(!m->sealed, -EPERM);
2445         assert_return(bus_type_is_trivial(type), -EINVAL);
2446         assert_return(ptr || size == 0, -EINVAL);
2447         assert_return(!m->poisoned, -ESTALE);
2448
2449         r = sd_bus_message_append_array_space(m, type, size, &p);
2450         if (r < 0)
2451                 return r;
2452
2453         if (size > 0)
2454                 memcpy(p, ptr, size);
2455
2456         return 0;
2457 }
2458
2459 _public_ int sd_bus_message_append_array_iovec(
2460                 sd_bus_message *m,
2461                 char type,
2462                 const struct iovec *iov,
2463                 unsigned n) {
2464
2465         size_t size;
2466         unsigned i;
2467         void *p;
2468         int r;
2469
2470         assert_return(m, -EINVAL);
2471         assert_return(!m->sealed, -EPERM);
2472         assert_return(bus_type_is_trivial(type), -EINVAL);
2473         assert_return(iov || n == 0, -EINVAL);
2474         assert_return(!m->poisoned, -ESTALE);
2475
2476         size = IOVEC_TOTAL_SIZE(iov, n);
2477
2478         r = sd_bus_message_append_array_space(m, type, size, &p);
2479         if (r < 0)
2480                 return r;
2481
2482         for (i = 0; i < n; i++) {
2483
2484                 if (iov[i].iov_base)
2485                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2486                 else
2487                         memset(p, 0, iov[i].iov_len);
2488
2489                 p = (uint8_t*) p + iov[i].iov_len;
2490         }
2491
2492         return 0;
2493 }
2494
2495 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2496                                                char type,
2497                                                sd_memfd *memfd) {
2498         _cleanup_close_ int copy_fd = -1;
2499         struct bus_body_part *part;
2500         ssize_t align, sz;
2501         uint64_t size;
2502         void *a;
2503         int r;
2504
2505         if (!m)
2506                 return -EINVAL;
2507         if (!memfd)
2508                 return -EINVAL;
2509         if (m->sealed)
2510                 return -EPERM;
2511         if (!bus_type_is_trivial(type))
2512                 return -EINVAL;
2513         if (m->poisoned)
2514                 return -ESTALE;
2515
2516         r = sd_memfd_set_sealed(memfd, true);
2517         if (r < 0)
2518                 return r;
2519
2520         copy_fd = sd_memfd_dup_fd(memfd);
2521         if (copy_fd < 0)
2522                 return copy_fd;
2523
2524         r = sd_memfd_get_size(memfd, &size);
2525         if (r < 0)
2526                 return r;
2527
2528         align = bus_type_get_alignment(type);
2529         sz = bus_type_get_size(type);
2530
2531         assert_se(align > 0);
2532         assert_se(sz > 0);
2533
2534         if (size % sz != 0)
2535                 return -EINVAL;
2536
2537         if (size > (uint64_t) (uint32_t) -1)
2538                 return -EINVAL;
2539
2540         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2541         if (r < 0)
2542                 return r;
2543
2544         a = message_extend_body(m, align, 0, false);
2545         if (!a)
2546                 return -ENOMEM;
2547
2548         part = message_append_part(m);
2549         if (!part)
2550                 return -ENOMEM;
2551
2552         part->memfd = copy_fd;
2553         part->sealed = true;
2554         part->size = size;
2555         copy_fd = -1;
2556
2557         m->header->body_size += size;
2558         message_extend_containers(m, size);
2559
2560         return sd_bus_message_close_container(m);
2561 }
2562
2563 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2564         _cleanup_close_ int copy_fd = -1;
2565         struct bus_body_part *part;
2566         struct bus_container *c;
2567         uint64_t size;
2568         void *a;
2569         int r;
2570
2571         assert_return(m, -EINVAL);
2572         assert_return(memfd, -EINVAL);
2573         assert_return(!m->sealed, -EPERM);
2574         assert_return(!m->poisoned, -ESTALE);
2575
2576         r = sd_memfd_set_sealed(memfd, true);
2577         if (r < 0)
2578                 return r;
2579
2580         copy_fd = sd_memfd_dup_fd(memfd);
2581         if (copy_fd < 0)
2582                 return copy_fd;
2583
2584         r = sd_memfd_get_size(memfd, &size);
2585         if (r < 0)
2586                 return r;
2587
2588         /* We require this to be NUL terminated */
2589         if (size == 0)
2590                 return -EINVAL;
2591
2592         if (size > (uint64_t) (uint32_t) -1)
2593                 return -EINVAL;
2594
2595         c = message_get_container(m);
2596         if (c->signature && c->signature[c->index]) {
2597                 /* Container signature is already set */
2598
2599                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2600                         return -ENXIO;
2601         } else {
2602                 char *e;
2603
2604                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2605                 if (c->enclosing != 0)
2606                         return -ENXIO;
2607
2608                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2609                 if (!e) {
2610                         m->poisoned = true;
2611                         return -ENOMEM;
2612                 }
2613         }
2614
2615         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2616                 a = message_extend_body(m, 4, 4, false);
2617                 if (!a)
2618                         return -ENOMEM;
2619
2620                 *(uint32_t*) a = size - 1;
2621         }
2622
2623         part = message_append_part(m);
2624         if (!part)
2625                 return -ENOMEM;
2626
2627         part->memfd = copy_fd;
2628         part->sealed = true;
2629         part->size = size;
2630         copy_fd = -1;
2631
2632         m->header->body_size += size;
2633         message_extend_containers(m, size);
2634
2635         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2636                 r = message_add_offset(m, m->header->body_size);
2637                 if (r < 0) {
2638                         m->poisoned = true;
2639                         return -ENOMEM;
2640                 }
2641         }
2642
2643         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2644                 c->index++;
2645
2646         return 0;
2647 }
2648
2649 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2650         char **i;
2651         int r;
2652
2653         assert_return(m, -EINVAL);
2654         assert_return(!m->sealed, -EPERM);
2655         assert_return(!m->poisoned, -ESTALE);
2656
2657         r = sd_bus_message_open_container(m, 'a', "s");
2658         if (r < 0)
2659                 return r;
2660
2661         STRV_FOREACH(i, l) {
2662                 r = sd_bus_message_append_basic(m, 's', *i);
2663                 if (r < 0)
2664                         return r;
2665         }
2666
2667         return sd_bus_message_close_container(m);
2668 }
2669
2670 static int bus_message_close_header(sd_bus_message *m) {
2671         uint8_t *a;
2672         size_t sz, i;
2673
2674         assert(m);
2675
2676         if (!BUS_MESSAGE_IS_GVARIANT(m))
2677                 return 0;
2678
2679         if (m->n_header_offsets < 1)
2680                 return 0;
2681
2682         assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2683
2684         sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2685
2686         a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2687         if (!a)
2688                 return -ENOMEM;
2689
2690         for (i = 0; i < m->n_header_offsets; i++)
2691                 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2692
2693         return 0;
2694 }
2695
2696 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2697         struct bus_body_part *part;
2698         size_t l, a;
2699         unsigned i;
2700         int r;
2701
2702         assert(m);
2703
2704         if (m->sealed)
2705                 return -EPERM;
2706
2707         if (m->n_containers > 0)
2708                 return -EBADMSG;
2709
2710         if (m->poisoned)
2711                 return -ESTALE;
2712
2713         /* In vtables the return signature of method calls is listed,
2714          * let's check if they match if this is a response */
2715         if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2716             m->enforced_reply_signature &&
2717             !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2718                 return -ENOMSG;
2719
2720         /* If gvariant marshalling is used we need to close the body structure */
2721         r = bus_message_close_struct(m, &m->root_container, false);
2722         if (r < 0)
2723                 return r;
2724
2725         /* If there's a non-trivial signature set, then add it in here */
2726         if (!isempty(m->root_container.signature)) {
2727                 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2728                 if (r < 0)
2729                         return r;
2730         }
2731
2732         if (m->n_fds > 0) {
2733                 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2734                 if (r < 0)
2735                         return r;
2736         }
2737
2738         r = bus_message_close_header(m);
2739         if (r < 0)
2740                 return r;
2741
2742         m->header->serial = serial;
2743
2744         /* Add padding at the end of the fields part, since we know
2745          * the body needs to start at an 8 byte alignment. We made
2746          * sure we allocated enough space for this, so all we need to
2747          * do here is to zero it out. */
2748         l = BUS_MESSAGE_FIELDS_SIZE(m);
2749         a = ALIGN8(l) - l;
2750         if (a > 0)
2751                 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
2752
2753         /* If this is something we can send as memfd, then let's seal
2754         the memfd now. Note that we can send memfds as payload only
2755         for directed messages, and not for broadcasts. */
2756         if (m->destination && m->bus && m->bus->use_memfd) {
2757                 MESSAGE_FOREACH_PART(part, i, m)
2758                         if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2759                                 bus_body_part_unmap(part);
2760
2761                                 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
2762                                         part->sealed = true;
2763                         }
2764         }
2765
2766         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2767         m->root_container.index = 0;
2768         m->root_container.offset_index = 0;
2769         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2770
2771         m->sealed = true;
2772
2773         return 0;
2774 }
2775
2776 int bus_body_part_map(struct bus_body_part *part) {
2777         void *p;
2778         size_t psz;
2779
2780         assert_se(part);
2781
2782         if (part->data)
2783                 return 0;
2784
2785         if (part->size <= 0)
2786                 return 0;
2787
2788         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2789         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2790                 static const uint8_t zeroes[7] = { };
2791                 part->data = (void*) zeroes;
2792                 return 0;
2793         }
2794
2795         psz = PAGE_ALIGN(part->size);
2796
2797         if (part->memfd >= 0)
2798                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2799         else if (part->is_zero)
2800                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2801         else
2802                 return -EINVAL;
2803
2804         if (p == MAP_FAILED)
2805                 return -errno;
2806
2807         part->mapped = psz;
2808         part->data = p;
2809         part->munmap_this = true;
2810
2811         return 0;
2812 }
2813
2814 void bus_body_part_unmap(struct bus_body_part *part) {
2815
2816         assert_se(part);
2817
2818         if (part->memfd < 0)
2819                 return;
2820
2821         if (!part->data)
2822                 return;
2823
2824         if (!part->munmap_this)
2825                 return;
2826
2827         assert_se(munmap(part->data, part->mapped) == 0);
2828
2829         part->data = NULL;
2830         part->mapped = 0;
2831         part->munmap_this = false;
2832
2833         return;
2834 }
2835
2836 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2837         size_t k, start, end;
2838
2839         assert(rindex);
2840         assert(align > 0);
2841
2842         start = ALIGN_TO((size_t) *rindex, align);
2843         end = start + nbytes;
2844
2845         if (end > sz)
2846                 return -EBADMSG;
2847
2848         /* Verify that padding is 0 */
2849         for (k = *rindex; k < start; k++)
2850                 if (((const uint8_t*) p)[k] != 0)
2851                         return -EBADMSG;
2852
2853         if (r)
2854                 *r = (uint8_t*) p + start;
2855
2856         *rindex = end;
2857
2858         return 1;
2859 }
2860
2861 static bool message_end_of_signature(sd_bus_message *m) {
2862         struct bus_container *c;
2863
2864         assert(m);
2865
2866         c = message_get_container(m);
2867         return !c->signature || c->signature[c->index] == 0;
2868 }
2869
2870 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2871         struct bus_container *c;
2872
2873         assert(m);
2874
2875         c = message_get_container(m);
2876         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2877                 return false;
2878
2879         if (BUS_MESSAGE_IS_GVARIANT(m))
2880                 return index >= c->end;
2881         else {
2882                 assert(c->array_size);
2883                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2884         }
2885 }
2886
2887 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2888         assert_return(m, -EINVAL);
2889         assert_return(m->sealed, -EPERM);
2890
2891         if (complete && m->n_containers > 0)
2892                 return false;
2893
2894         if (message_end_of_signature(m))
2895                 return true;
2896
2897         if (message_end_of_array(m, m->rindex))
2898                 return true;
2899
2900         return false;
2901 }
2902
2903 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2904         struct bus_body_part *part;
2905         size_t begin;
2906         int r;
2907
2908         assert(m);
2909
2910         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2911                 part = m->cached_rindex_part;
2912                 begin = m->cached_rindex_part_begin;
2913         } else {
2914                 part = &m->body;
2915                 begin = 0;
2916         }
2917
2918         while (part) {
2919                 if (index < begin)
2920                         return NULL;
2921
2922                 if (index + sz <= begin + part->size) {
2923
2924                         r = bus_body_part_map(part);
2925                         if (r < 0)
2926                                 return NULL;
2927
2928                         if (p)
2929                                 *p = (uint8_t*) part->data + index - begin;
2930
2931                         m->cached_rindex_part = part;
2932                         m->cached_rindex_part_begin = begin;
2933
2934                         return part;
2935                 }
2936
2937                 begin += part->size;
2938                 part = part->next;
2939         }
2940
2941         return NULL;
2942 }
2943
2944 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
2945         int r;
2946
2947         assert(m);
2948         assert(c);
2949         assert(rindex);
2950
2951         if (!BUS_MESSAGE_IS_GVARIANT(m))
2952                 return 0;
2953
2954         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2955                 int sz;
2956
2957                 sz = bus_gvariant_get_size(c->signature);
2958                 if (sz < 0) {
2959                         int alignment;
2960
2961                         if (c->offset_index+1 >= c->n_offsets)
2962                                 goto end;
2963
2964                         /* Variable-size array */
2965
2966                         alignment = bus_gvariant_get_alignment(c->signature);
2967                         assert(alignment > 0);
2968
2969                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
2970                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
2971                 } else {
2972
2973                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
2974                                 goto end;
2975
2976                         /* Fixed-size array */
2977                         *rindex = c->begin + (c->offset_index+1) * sz;
2978                         c->item_size = sz;
2979                 }
2980
2981                 c->offset_index++;
2982
2983         } else if (c->enclosing == 0 ||
2984                    c->enclosing == SD_BUS_TYPE_STRUCT ||
2985                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
2986
2987                 int alignment;
2988                 size_t n, j;
2989
2990                 if (c->offset_index+1 >= c->n_offsets)
2991                         goto end;
2992
2993                 r = signature_element_length(c->signature + c->index, &n);
2994                 if (r < 0)
2995                         return r;
2996
2997                 r = signature_element_length(c->signature + c->index + n, &j);
2998                 if (r < 0)
2999                         return r;
3000                 else {
3001                         char t[j+1];
3002                         memcpy(t, c->signature + c->index + n, j);
3003                         t[j] = 0;
3004
3005                         alignment = bus_gvariant_get_alignment(t);
3006                 }
3007
3008                 assert(alignment > 0);
3009
3010                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3011                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3012
3013                 c->offset_index++;
3014
3015         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3016                 goto end;
3017         else
3018                 assert_not_reached("Unknown container type");
3019
3020         return 0;
3021
3022 end:
3023         /* Reached the end */
3024         *rindex = c->end;
3025         c->item_size = 0;
3026         return 0;
3027 }
3028
3029
3030 static int message_peek_body(
3031                 sd_bus_message *m,
3032                 size_t *rindex,
3033                 size_t align,
3034                 size_t nbytes,
3035                 void **ret) {
3036
3037         size_t k, start, end, padding;
3038         struct bus_body_part *part;
3039         uint8_t *q;
3040
3041         assert(m);
3042         assert(rindex);
3043         assert(align > 0);
3044
3045         start = ALIGN_TO((size_t) *rindex, align);
3046         padding = start - *rindex;
3047         end = start + nbytes;
3048
3049         if (end > BUS_MESSAGE_BODY_SIZE(m))
3050                 return -EBADMSG;
3051
3052         part = find_part(m, *rindex, padding, (void**) &q);
3053         if (!part)
3054                 return -EBADMSG;
3055
3056         if (q) {
3057                 /* Verify padding */
3058                 for (k = 0; k < padding; k++)
3059                         if (q[k] != 0)
3060                                 return -EBADMSG;
3061         }
3062
3063         part = find_part(m, start, nbytes, (void**) &q);
3064         if (!part || (nbytes > 0 && !q))
3065                 return -EBADMSG;
3066
3067         *rindex = end;
3068
3069         if (ret)
3070                 *ret = q;
3071
3072         return 0;
3073 }
3074
3075 static bool validate_nul(const char *s, size_t l) {
3076
3077         /* Check for NUL chars in the string */
3078         if (memchr(s, 0, l))
3079                 return false;
3080
3081         /* Check for NUL termination */
3082         if (s[l] != 0)
3083                 return false;
3084
3085         return true;
3086 }
3087
3088 static bool validate_string(const char *s, size_t l) {
3089
3090         if (!validate_nul(s, l))
3091                 return false;
3092
3093         /* Check if valid UTF8 */
3094         if (!utf8_is_valid(s))
3095                 return false;
3096
3097         return true;
3098 }
3099
3100 static bool validate_signature(const char *s, size_t l) {
3101
3102         if (!validate_nul(s, l))
3103                 return false;
3104
3105         /* Check if valid signature */
3106         if (!signature_is_valid(s, true))
3107                 return false;
3108
3109         return true;
3110 }
3111
3112 static bool validate_object_path(const char *s, size_t l) {
3113
3114         if (!validate_nul(s, l))
3115                 return false;
3116
3117         if (!object_path_is_valid(s))
3118                 return false;
3119
3120         return true;
3121 }
3122
3123 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3124         struct bus_container *c;
3125         size_t rindex;
3126         void *q;
3127         int r;
3128
3129         assert_return(m, -EINVAL);
3130         assert_return(m->sealed, -EPERM);
3131         assert_return(bus_type_is_basic(type), -EINVAL);
3132
3133         if (message_end_of_signature(m))
3134                 return -ENXIO;
3135
3136         if (message_end_of_array(m, m->rindex))
3137                 return 0;
3138
3139         c = message_get_container(m);
3140         if (c->signature[c->index] != type)
3141                 return -ENXIO;
3142
3143         rindex = m->rindex;
3144
3145         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3146
3147                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3148                         bool ok;
3149
3150                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3151                         if (r < 0)
3152                                 return r;
3153
3154                         if (type == SD_BUS_TYPE_STRING)
3155                                 ok = validate_string(q, c->item_size-1);
3156                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3157                                 ok = validate_object_path(q, c->item_size-1);
3158                         else
3159                                 ok = validate_signature(q, c->item_size-1);
3160
3161                         if (!ok)
3162                                 return -EBADMSG;
3163
3164                         if (p)
3165                                 *(const char**) p = q;
3166                 } else {
3167                         int sz, align;
3168
3169                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3170                         assert(sz > 0);
3171                         if ((size_t) sz != c->item_size)
3172                                 return -EBADMSG;
3173
3174                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3175                         assert(align > 0);
3176
3177                         r = message_peek_body(m, &rindex, align, c->item_size, &q);
3178                         if (r < 0)
3179                                 return r;
3180
3181                         switch (type) {
3182
3183                         case SD_BUS_TYPE_BYTE:
3184                                 if (p)
3185                                         *(uint8_t*) p = *(uint8_t*) q;
3186                                 break;
3187
3188                         case SD_BUS_TYPE_BOOLEAN:
3189                                 if (p)
3190                                         *(int*) p = !!*(uint8_t*) q;
3191                                 break;
3192
3193                         case SD_BUS_TYPE_INT16:
3194                         case SD_BUS_TYPE_UINT16:
3195                                 if (p)
3196                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3197                                 break;
3198
3199                         case SD_BUS_TYPE_INT32:
3200                         case SD_BUS_TYPE_UINT32:
3201                                 if (p)
3202                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3203                                 break;
3204
3205                         case SD_BUS_TYPE_INT64:
3206                         case SD_BUS_TYPE_UINT64:
3207                         case SD_BUS_TYPE_DOUBLE:
3208                                 if (p)
3209                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3210                                 break;
3211
3212                         case SD_BUS_TYPE_UNIX_FD: {
3213                                 uint32_t j;
3214
3215                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3216                                 if (j >= m->n_fds)
3217                                         return -EBADMSG;
3218
3219                                 if (p)
3220                                         *(int*) p = m->fds[j];
3221
3222                                 break;
3223                         }
3224
3225                         default:
3226                                 assert_not_reached("unexpected type");
3227                         }
3228                 }
3229
3230                 r = container_next_item(m, c, &rindex);
3231                 if (r < 0)
3232                         return r;
3233         } else {
3234
3235                 rindex = m->rindex;
3236
3237                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3238                         uint32_t l;
3239                         bool ok;
3240
3241                         r = message_peek_body(m, &rindex, 4, 4, &q);
3242                         if (r < 0)
3243                                 return r;
3244
3245                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3246                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3247                         if (r < 0)
3248                                 return r;
3249
3250                         if (type == SD_BUS_TYPE_OBJECT_PATH)
3251                                 ok = validate_object_path(q, l);
3252                         else
3253                                 ok = validate_string(q, l);
3254                         if (!ok)
3255                                 return -EBADMSG;
3256
3257                         if (p)
3258                                 *(const char**) p = q;
3259
3260                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3261                         uint8_t l;
3262
3263                         r = message_peek_body(m, &rindex, 1, 1, &q);
3264                         if (r < 0)
3265                                 return r;
3266
3267                         l = *(uint8_t*) q;
3268                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3269                         if (r < 0)
3270                                 return r;
3271
3272                         if (!validate_signature(q, l))
3273                                 return -EBADMSG;
3274
3275                         if (p)
3276                                 *(const char**) p = q;
3277
3278                 } else {
3279                         ssize_t sz, align;
3280
3281                         align = bus_type_get_alignment(type);
3282                         assert(align > 0);
3283
3284                         sz = bus_type_get_size(type);
3285                         assert(sz > 0);
3286
3287                         r = message_peek_body(m, &rindex, align, sz, &q);
3288                         if (r < 0)
3289                                 return r;
3290
3291                         switch (type) {
3292
3293                         case SD_BUS_TYPE_BYTE:
3294                                 if (p)
3295                                         *(uint8_t*) p = *(uint8_t*) q;
3296                                 break;
3297
3298                         case SD_BUS_TYPE_BOOLEAN:
3299                                 if (p)
3300                                         *(int*) p = !!*(uint32_t*) q;
3301                                 break;
3302
3303                         case SD_BUS_TYPE_INT16:
3304                         case SD_BUS_TYPE_UINT16:
3305                                 if (p)
3306                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3307                                 break;
3308
3309                         case SD_BUS_TYPE_INT32:
3310                         case SD_BUS_TYPE_UINT32:
3311                                 if (p)
3312                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3313                                 break;
3314
3315                         case SD_BUS_TYPE_INT64:
3316                         case SD_BUS_TYPE_UINT64:
3317                         case SD_BUS_TYPE_DOUBLE:
3318                                 if (p)
3319                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3320                                 break;
3321
3322                         case SD_BUS_TYPE_UNIX_FD: {
3323                                 uint32_t j;
3324
3325                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3326                                 if (j >= m->n_fds)
3327                                         return -EBADMSG;
3328
3329                                 if (p)
3330                                         *(int*) p = m->fds[j];
3331                                 break;
3332                         }
3333
3334                         default:
3335                                 assert_not_reached("Unknown basic type...");
3336                         }
3337                 }
3338         }
3339
3340         m->rindex = rindex;
3341
3342         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3343                 c->index++;
3344
3345         return 1;
3346 }
3347
3348 static int bus_message_enter_array(
3349                 sd_bus_message *m,
3350                 struct bus_container *c,
3351                 const char *contents,
3352                 uint32_t **array_size,
3353                 size_t *item_size,
3354                 size_t **offsets,
3355                 size_t *n_offsets) {
3356
3357         size_t rindex;
3358         void *q;
3359         int r, alignment;
3360
3361         assert(m);
3362         assert(c);
3363         assert(contents);
3364         assert(array_size);
3365         assert(item_size);
3366         assert(offsets);
3367         assert(n_offsets);
3368
3369         if (!signature_is_single(contents, true))
3370                 return -EINVAL;
3371
3372         if (!c->signature || c->signature[c->index] == 0)
3373                 return -ENXIO;
3374
3375         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3376                 return -ENXIO;
3377
3378         if (!startswith(c->signature + c->index + 1, contents))
3379                 return -ENXIO;
3380
3381         rindex = m->rindex;
3382
3383         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3384                 /* dbus1 */
3385
3386                 r = message_peek_body(m, &rindex, 4, 4, &q);
3387                 if (r < 0)
3388                         return r;
3389
3390                 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3391                         return -EBADMSG;
3392
3393                 alignment = bus_type_get_alignment(contents[0]);
3394                 if (alignment < 0)
3395                         return alignment;
3396
3397                 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3398                 if (r < 0)
3399                         return r;
3400
3401                 *array_size = (uint32_t*) q;
3402
3403         } else if (c->item_size <= 0) {
3404
3405                 /* gvariant: empty array */
3406                 *item_size = 0;
3407                 *offsets = NULL;
3408                 *n_offsets = 0;
3409
3410         } else if (bus_gvariant_is_fixed_size(contents)) {
3411
3412                 /* gvariant: fixed length array */
3413                 *item_size = bus_gvariant_get_size(contents);
3414                 *offsets = NULL;
3415                 *n_offsets = 0;
3416
3417         } else {
3418                 size_t where, p = 0, framing, sz;
3419                 unsigned i;
3420
3421                 /* gvariant: variable length array */
3422                 sz = determine_word_size(c->item_size, 0);
3423
3424                 where = rindex + c->item_size - sz;
3425                 r = message_peek_body(m, &where, 1, sz, &q);
3426                 if (r < 0)
3427                         return r;
3428
3429                 framing = read_word_le(q, sz);
3430                 if (framing > c->item_size - sz)
3431                         return -EBADMSG;
3432                 if ((c->item_size - framing) % sz != 0)
3433                         return -EBADMSG;
3434
3435                 *n_offsets = (c->item_size - framing) / sz;
3436
3437                 where = rindex + framing;
3438                 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3439                 if (r < 0)
3440                         return r;
3441
3442                 *offsets = new(size_t, *n_offsets);
3443                 if (!*offsets)
3444                         return -ENOMEM;
3445
3446                 for (i = 0; i < *n_offsets; i++) {
3447                         size_t x;
3448
3449                         x = read_word_le((uint8_t*) q + i * sz, sz);
3450                         if (x > c->item_size - sz)
3451                                 return -EBADMSG;
3452                         if (x < p)
3453                                 return -EBADMSG;
3454
3455                         (*offsets)[i] = rindex + x;
3456                         p = x;
3457                 }
3458
3459                 *item_size = (*offsets)[0] - rindex;
3460         }
3461
3462         m->rindex = rindex;
3463
3464         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3465                 c->index += 1 + strlen(contents);
3466
3467         return 1;
3468 }
3469
3470 static int bus_message_enter_variant(
3471                 sd_bus_message *m,
3472                 struct bus_container *c,
3473                 const char *contents,
3474                 size_t *item_size) {
3475
3476         size_t rindex;
3477         uint8_t l;
3478         void *q;
3479         int r;
3480
3481         assert(m);
3482         assert(c);
3483         assert(contents);
3484         assert(item_size);
3485
3486         if (!signature_is_single(contents, false))
3487                 return -EINVAL;
3488
3489         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3490                 return -EINVAL;
3491
3492         if (!c->signature || c->signature[c->index] == 0)
3493                 return -ENXIO;
3494
3495         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3496                 return -ENXIO;
3497
3498         rindex = m->rindex;
3499
3500         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3501                 size_t k, where;
3502
3503                 k = strlen(contents);
3504                 if (1+k > c->item_size)
3505                         return -EBADMSG;
3506
3507                 where = rindex + c->item_size - (1+k);
3508                 r = message_peek_body(m, &where, 1, 1+k, &q);
3509                 if (r < 0)
3510                         return r;
3511
3512                 if (*(char*) q != 0)
3513                         return -EBADMSG;
3514
3515                 if (memcmp((uint8_t*) q+1, contents, k))
3516                         return -ENXIO;
3517
3518                 *item_size = c->item_size - (1+k);
3519
3520         } else {
3521                 r = message_peek_body(m, &rindex, 1, 1, &q);
3522                 if (r < 0)
3523                         return r;
3524
3525                 l = *(uint8_t*) q;
3526                 r = message_peek_body(m, &rindex, 1, l+1, &q);
3527                 if (r < 0)
3528                         return r;
3529
3530                 if (!validate_signature(q, l))
3531                         return -EBADMSG;
3532
3533                 if (!streq(q, contents))
3534                         return -ENXIO;
3535         }
3536
3537         m->rindex = rindex;
3538
3539         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3540                 c->index++;
3541
3542         return 1;
3543 }
3544
3545 static int build_struct_offsets(
3546                 sd_bus_message *m,
3547                 const char *signature,
3548                 size_t size,
3549                 size_t *item_size,
3550                 size_t **offsets,
3551                 size_t *n_offsets) {
3552
3553         unsigned n_variable = 0, n_total = 0, v;
3554         size_t previous = 0, where;
3555         const char *p;
3556         size_t sz;
3557         void *q;
3558         int r;
3559
3560         assert(m);
3561         assert(item_size);
3562         assert(offsets);
3563         assert(n_offsets);
3564
3565         if (isempty(signature)) {
3566                 *item_size = 0;
3567                 *offsets = NULL;
3568                 *n_offsets = 0;
3569                 return 0;
3570         }
3571
3572         sz = determine_word_size(size, 0);
3573         if (sz <= 0)
3574                 return -EBADMSG;
3575
3576         /* First, loop over signature and count variable elements and
3577          * elements in general. We use this to know how large the
3578          * offset array is at the end of the structure. Note that
3579          * GVariant only stores offsets for all variable size elements
3580          * that are not the last item. */
3581
3582         p = signature;
3583         while (*p != 0) {
3584                 size_t n;
3585
3586                 r = signature_element_length(p, &n);
3587                 if (r < 0)
3588                         return r;
3589                 else {
3590                         char t[n+1];
3591
3592                         memcpy(t, p, n);
3593                         t[n] = 0;
3594
3595                         r = bus_gvariant_is_fixed_size(t);
3596                 }
3597
3598                 if (r < 0)
3599                         return r;
3600                 if (r == 0 && p[n] != 0) /* except the last item */
3601                         n_variable ++;
3602                 n_total++;
3603
3604                 p += n;
3605         }
3606
3607         if (size < n_variable * sz)
3608                 return -EBADMSG;
3609
3610         where = m->rindex + size - (n_variable * sz);
3611         r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3612         if (r < 0)
3613                 return r;
3614
3615         v = n_variable;
3616
3617         *offsets = new(size_t, n_total);
3618         if (!*offsets)
3619                 return -ENOMEM;
3620
3621         *n_offsets = 0;
3622
3623         /* Second, loop again and build an offset table */
3624         p = signature;
3625         while (*p != 0) {
3626                 size_t n, offset;
3627                 int k;
3628
3629                 r = signature_element_length(p, &n);
3630                 if (r < 0)
3631                         return r;
3632                 else {
3633                         char t[n+1];
3634
3635                         memcpy(t, p, n);
3636                         t[n] = 0;
3637
3638                         k = bus_gvariant_get_size(t);
3639                         if (k < 0) {
3640                                 size_t x;
3641
3642                                 /* variable size */
3643                                 if (v > 0) {
3644                                         v--;
3645
3646                                         x = read_word_le((uint8_t*) q + v*sz, sz);
3647                                         if (x >= size)
3648                                                 return -EBADMSG;
3649                                         if (m->rindex + x < previous)
3650                                                 return -EBADMSG;
3651                                 } else
3652                                         /* The last item's end
3653                                          * is determined from
3654                                          * the start of the
3655                                          * offset array */
3656                                         x = size - (n_variable * sz);
3657
3658                                 offset = m->rindex + x;
3659
3660                         } else {
3661                                 size_t align;
3662
3663                                 /* fixed size */
3664                                 align = bus_gvariant_get_alignment(t);
3665                                 assert(align > 0);
3666
3667                                 offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3668                         }
3669                 }
3670
3671                 previous = (*offsets)[(*n_offsets)++] = offset;
3672                 p += n;
3673         }
3674
3675         assert(v == 0);
3676         assert(*n_offsets == n_total);
3677
3678         *item_size = (*offsets)[0] - m->rindex;
3679         return 0;
3680 }
3681
3682 static int enter_struct_or_dict_entry(
3683                 sd_bus_message *m,
3684                 struct bus_container *c,
3685                 const char *contents,
3686                 size_t *item_size,
3687                 size_t **offsets,
3688                 size_t *n_offsets) {
3689
3690         int r;
3691
3692         assert(m);
3693         assert(c);
3694         assert(contents);
3695         assert(item_size);
3696         assert(offsets);
3697         assert(n_offsets);
3698
3699         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3700
3701                 /* dbus1 */
3702                 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3703                 if (r < 0)
3704                         return r;
3705
3706         } else if (c->item_size <= 0) {
3707
3708                 /* gvariant empty struct */
3709                 *item_size = 0;
3710                 *offsets = NULL;
3711                 *n_offsets = 0;
3712         } else
3713                 /* gvariant with contents */
3714                 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3715
3716         return 0;
3717 }
3718
3719 static int bus_message_enter_struct(
3720                 sd_bus_message *m,
3721                 struct bus_container *c,
3722                 const char *contents,
3723                 size_t *item_size,
3724                 size_t **offsets,
3725                 size_t *n_offsets) {
3726
3727         size_t l;
3728         int r;
3729
3730         assert(m);
3731         assert(c);
3732         assert(contents);
3733         assert(item_size);
3734         assert(offsets);
3735         assert(n_offsets);
3736
3737         if (!signature_is_valid(contents, false))
3738                 return -EINVAL;
3739
3740         if (!c->signature || c->signature[c->index] == 0)
3741                 return -ENXIO;
3742
3743         l = strlen(contents);
3744
3745         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3746             !startswith(c->signature + c->index + 1, contents) ||
3747             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3748                 return -ENXIO;
3749
3750         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3751         if (r < 0)
3752                 return r;
3753
3754         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3755                 c->index += 1 + l + 1;
3756
3757         return 1;
3758 }
3759
3760 static int bus_message_enter_dict_entry(
3761                 sd_bus_message *m,
3762                 struct bus_container *c,
3763                 const char *contents,
3764                 size_t *item_size,
3765                 size_t **offsets,
3766                 size_t *n_offsets) {
3767
3768         size_t l;
3769         int r;
3770
3771         assert(m);
3772         assert(c);
3773         assert(contents);
3774
3775         if (!signature_is_pair(contents))
3776                 return -EINVAL;
3777
3778         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3779                 return -ENXIO;
3780
3781         if (!c->signature || c->signature[c->index] == 0)
3782                 return 0;
3783
3784         l = strlen(contents);
3785
3786         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3787             !startswith(c->signature + c->index + 1, contents) ||
3788             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3789                 return -ENXIO;
3790
3791         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3792         if (r < 0)
3793                 return r;
3794
3795         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3796                 c->index += 1 + l + 1;
3797
3798         return 1;
3799 }
3800
3801 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3802                                             char type,
3803                                             const char *contents) {
3804         struct bus_container *c, *w;
3805         uint32_t *array_size = NULL;
3806         char *signature;
3807         size_t before;
3808         size_t *offsets = NULL;
3809         size_t n_offsets = 0, item_size = 0;
3810         int r;
3811
3812         assert_return(m, -EINVAL);
3813         assert_return(m->sealed, -EPERM);
3814         assert_return(type != 0 || !contents, -EINVAL);
3815
3816         if (type == 0 || !contents) {
3817                 const char *cc;
3818                 char tt;
3819
3820                 /* Allow entering into anonymous containers */
3821                 r = sd_bus_message_peek_type(m, &tt, &cc);
3822                 if (r < 0)
3823                         return r;
3824
3825                 if (type != 0 && type != tt)
3826                         return -ENXIO;
3827
3828                 if (contents && !streq(contents, cc))
3829                         return -ENXIO;
3830
3831                 type = tt;
3832                 contents = cc;
3833         }
3834
3835         /*
3836          * We enforce a global limit on container depth, that is much
3837          * higher than the 32 structs and 32 arrays the specification
3838          * mandates. This is simpler to implement for us, and we need
3839          * this only to ensure our container array doesn't grow
3840          * without bounds. We are happy to return any data from a
3841          * message as long as the data itself is valid, even if the
3842          * overall message might be not.
3843          *
3844          * Note that the message signature is validated when
3845          * parsing the headers, and that validation does check the
3846          * 32/32 limit.
3847          *
3848          * Note that the specification defines no limits on the depth
3849          * of stacked variants, but we do.
3850          */
3851         if (m->n_containers >= BUS_CONTAINER_DEPTH)
3852                 return -EBADMSG;
3853
3854         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3855         if (!w)
3856                 return -ENOMEM;
3857         m->containers = w;
3858
3859         if (message_end_of_signature(m))
3860                 return -ENXIO;
3861
3862         if (message_end_of_array(m, m->rindex))
3863                 return 0;
3864
3865         c = message_get_container(m);
3866
3867         signature = strdup(contents);
3868         if (!signature)
3869                 return -ENOMEM;
3870
3871         c->saved_index = c->index;
3872         before = m->rindex;
3873
3874         if (type == SD_BUS_TYPE_ARRAY)
3875                 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3876         else if (type == SD_BUS_TYPE_VARIANT)
3877                 r = bus_message_enter_variant(m, c, contents, &item_size);
3878         else if (type == SD_BUS_TYPE_STRUCT)
3879                 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3880         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3881                 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3882         else
3883                 r = -EINVAL;
3884
3885         if (r <= 0) {
3886                 free(signature);
3887                 free(offsets);
3888                 return r;
3889         }
3890
3891         /* OK, let's fill it in */
3892         w += m->n_containers++;
3893         w->enclosing = type;
3894         w->signature = signature;
3895         w->index = 0;
3896
3897         w->before = before;
3898         w->begin = m->rindex;
3899         w->end = m->rindex + c->item_size;
3900
3901         w->array_size = array_size;
3902         w->item_size = item_size;
3903         w->offsets = offsets;
3904         w->n_offsets = n_offsets;
3905         w->offset_index = 0;
3906
3907         return 1;
3908 }
3909
3910 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3911         struct bus_container *c;
3912         unsigned saved;
3913         int r;
3914
3915         assert_return(m, -EINVAL);
3916         assert_return(m->sealed, -EPERM);
3917         assert_return(m->n_containers > 0, -ENXIO);
3918
3919         c = message_get_container(m);
3920
3921         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
3922                 if (c->signature && c->signature[c->index] != 0)
3923                         return -EBUSY;
3924         }
3925
3926         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3927                 if (m->rindex < c->end)
3928                         return -EBUSY;
3929
3930         } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3931                 uint32_t l;
3932
3933                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3934                 if (c->begin + l != m->rindex)
3935                         return -EBUSY;
3936         }
3937
3938         free(c->signature);
3939         free(c->offsets);
3940         m->n_containers--;
3941
3942         c = message_get_container(m);
3943
3944         saved = c->index;
3945         c->index = c->saved_index;
3946         r = container_next_item(m, c, &m->rindex);
3947         c->index = saved;
3948         if (r < 0)
3949                 return r;
3950
3951         return 1;
3952 }
3953
3954 static void message_quit_container(sd_bus_message *m) {
3955         struct bus_container *c;
3956
3957         assert(m);
3958         assert(m->sealed);
3959         assert(m->n_containers > 0);
3960
3961         c = message_get_container(m);
3962
3963         /* Undo seeks */
3964         assert(m->rindex >= c->before);
3965         m->rindex = c->before;
3966
3967         /* Free container */
3968         free(c->signature);
3969         free(c->offsets);
3970         m->n_containers--;
3971
3972         /* Correct index of new top-level container */
3973         c = message_get_container(m);
3974         c->index = c->saved_index;
3975 }
3976
3977 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3978         struct bus_container *c;
3979         int r;
3980
3981         assert_return(m, -EINVAL);
3982         assert_return(m->sealed, -EPERM);
3983
3984         if (message_end_of_signature(m))
3985                 goto eof;
3986
3987         if (message_end_of_array(m, m->rindex))
3988                 goto eof;
3989
3990         c = message_get_container(m);
3991
3992         if (bus_type_is_basic(c->signature[c->index])) {
3993                 if (contents)
3994                         *contents = NULL;
3995                 if (type)
3996                         *type = c->signature[c->index];
3997                 return 1;
3998         }
3999
4000         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4001
4002                 if (contents) {
4003                         size_t l;
4004                         char *sig;
4005
4006                         r = signature_element_length(c->signature+c->index+1, &l);
4007                         if (r < 0)
4008                                 return r;
4009
4010                         assert(l >= 1);
4011
4012                         sig = strndup(c->signature + c->index + 1, l);
4013                         if (!sig)
4014                                 return -ENOMEM;
4015
4016                         free(m->peeked_signature);
4017                         m->peeked_signature = sig;
4018
4019                         *contents = sig;
4020                 }
4021
4022                 if (type)
4023                         *type = SD_BUS_TYPE_ARRAY;
4024
4025                 return 1;
4026         }
4027
4028         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4029             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4030
4031                 if (contents) {
4032                         size_t l;
4033                         char *sig;
4034
4035                         r = signature_element_length(c->signature+c->index, &l);
4036                         if (r < 0)
4037                                 return r;
4038
4039                         assert(l >= 2);
4040                         sig = strndup(c->signature + c->index + 1, l - 2);
4041                         if (!sig)
4042                                 return -ENOMEM;
4043
4044                         free(m->peeked_signature);
4045                         m->peeked_signature = sig;
4046
4047                         *contents = sig;
4048                 }
4049
4050                 if (type)
4051                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4052
4053                 return 1;
4054         }
4055
4056         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4057                 if (contents) {
4058                         void *q;
4059
4060                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4061                                 size_t k;
4062
4063                                 if (c->item_size < 2)
4064                                         return -EBADMSG;
4065
4066                                 /* Look for the NUL delimiter that
4067                                    separates the payload from the
4068                                    signature. Since the body might be
4069                                    in a different part that then the
4070                                    signature we map byte by byte. */
4071
4072                                 for (k = 2; k <= c->item_size; k++) {
4073                                         size_t where;
4074
4075                                         where = m->rindex + c->item_size - k;
4076                                         r = message_peek_body(m, &where, 1, k, &q);
4077                                         if (r < 0)
4078                                                 return r;
4079
4080                                         if (*(char*) q == 0)
4081                                                 break;
4082                                 }
4083
4084                                 if (k > c->item_size)
4085                                         return -EBADMSG;
4086
4087                                 free(m->peeked_signature);
4088                                 m->peeked_signature = strndup((char*) q + 1, k - 1);
4089                                 if (!m->peeked_signature)
4090                                         return -ENOMEM;
4091
4092                                 if (!signature_is_valid(m->peeked_signature, true))
4093                                         return -EBADMSG;
4094
4095                                 *contents = m->peeked_signature;
4096                         } else {
4097                                 size_t rindex, l;
4098
4099                                 rindex = m->rindex;
4100                                 r = message_peek_body(m, &rindex, 1, 1, &q);
4101                                 if (r < 0)
4102                                         return r;
4103
4104                                 l = *(uint8_t*) q;
4105                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
4106                                 if (r < 0)
4107                                         return r;
4108
4109                                 if (!validate_signature(q, l))
4110                                         return -EBADMSG;
4111
4112                                 *contents = q;
4113                         }
4114                 }
4115
4116                 if (type)
4117                         *type = SD_BUS_TYPE_VARIANT;
4118
4119                 return 1;
4120         }
4121
4122         return -EINVAL;
4123
4124 eof:
4125         if (type)
4126                 *type = 0;
4127         if (contents)
4128                 *contents = NULL;
4129         return 0;
4130 }
4131
4132 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4133         struct bus_container *c;
4134
4135         assert_return(m, -EINVAL);
4136         assert_return(m->sealed, -EPERM);
4137
4138         if (complete) {
4139                 message_reset_containers(m);
4140                 m->rindex = 0;
4141
4142                 c = message_get_container(m);
4143         } else {
4144                 c = message_get_container(m);
4145
4146                 c->offset_index = 0;
4147                 c->index = 0;
4148                 m->rindex = c->begin;
4149         }
4150
4151         c->offset_index = 0;
4152         c->item_size = c->n_offsets > 0 ? c->offsets[0] : c->end;
4153
4154         return !isempty(c->signature);
4155 }
4156
4157 static int message_read_ap(
4158                 sd_bus_message *m,
4159                 const char *types,
4160                 va_list ap) {
4161
4162         unsigned n_array, n_struct;
4163         TypeStack stack[BUS_CONTAINER_DEPTH];
4164         unsigned stack_ptr = 0;
4165         unsigned n_loop = 0;
4166         int r;
4167
4168         assert(m);
4169
4170         if (isempty(types))
4171                 return 0;
4172
4173         /* Ideally, we'd just call ourselves recursively on every
4174          * complex type. However, the state of a va_list that is
4175          * passed to a function is undefined after that function
4176          * returns. This means we need to docode the va_list linearly
4177          * in a single stackframe. We hence implement our own
4178          * home-grown stack in an array. */
4179
4180         n_array = (unsigned) -1; /* lenght of current array entries */
4181         n_struct = strlen(types); /* length of current struct contents signature */
4182
4183         for (;;) {
4184                 const char *t;
4185
4186                 n_loop++;
4187
4188                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4189                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4190                         if (r < 0)
4191                                 return r;
4192                         if (r == 0)
4193                                 break;
4194
4195                         r = sd_bus_message_exit_container(m);
4196                         if (r < 0)
4197                                 return r;
4198
4199                         continue;
4200                 }
4201
4202                 t = types;
4203                 if (n_array != (unsigned) -1)
4204                         n_array --;
4205                 else {
4206                         types ++;
4207                         n_struct--;
4208                 }
4209
4210                 switch (*t) {
4211
4212                 case SD_BUS_TYPE_BYTE:
4213                 case SD_BUS_TYPE_BOOLEAN:
4214                 case SD_BUS_TYPE_INT16:
4215                 case SD_BUS_TYPE_UINT16:
4216                 case SD_BUS_TYPE_INT32:
4217                 case SD_BUS_TYPE_UINT32:
4218                 case SD_BUS_TYPE_INT64:
4219                 case SD_BUS_TYPE_UINT64:
4220                 case SD_BUS_TYPE_DOUBLE:
4221                 case SD_BUS_TYPE_STRING:
4222                 case SD_BUS_TYPE_OBJECT_PATH:
4223                 case SD_BUS_TYPE_SIGNATURE:
4224                 case SD_BUS_TYPE_UNIX_FD: {
4225                         void *p;
4226
4227                         p = va_arg(ap, void*);
4228                         r = sd_bus_message_read_basic(m, *t, p);
4229                         if (r < 0)
4230                                 return r;
4231                         if (r == 0) {
4232                                 if (n_loop <= 1)
4233                                         return 0;
4234
4235                                 return -ENXIO;
4236                         }
4237
4238                         break;
4239                 }
4240
4241                 case SD_BUS_TYPE_ARRAY: {
4242                         size_t k;
4243
4244                         r = signature_element_length(t + 1, &k);
4245                         if (r < 0)
4246                                 return r;
4247
4248                         {
4249                                 char s[k + 1];
4250                                 memcpy(s, t + 1, k);
4251                                 s[k] = 0;
4252
4253                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4254                                 if (r < 0)
4255                                         return r;
4256                                 if (r == 0) {
4257                                         if (n_loop <= 1)
4258                                                 return 0;
4259
4260                                         return -ENXIO;
4261                                 }
4262                         }
4263
4264                         if (n_array == (unsigned) -1) {
4265                                 types += k;
4266                                 n_struct -= k;
4267                         }
4268
4269                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4270                         if (r < 0)
4271                                 return r;
4272
4273                         types = t + 1;
4274                         n_struct = k;
4275                         n_array = va_arg(ap, unsigned);
4276
4277                         break;
4278                 }
4279
4280                 case SD_BUS_TYPE_VARIANT: {
4281                         const char *s;
4282
4283                         s = va_arg(ap, const char *);
4284                         if (!s)
4285                                 return -EINVAL;
4286
4287                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4288                         if (r < 0)
4289                                 return r;
4290                         if (r == 0) {
4291                                 if (n_loop <= 1)
4292                                         return 0;
4293
4294                                 return -ENXIO;
4295                         }
4296
4297                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4298                         if (r < 0)
4299                                 return r;
4300
4301                         types = s;
4302                         n_struct = strlen(s);
4303                         n_array = (unsigned) -1;
4304
4305                         break;
4306                 }
4307
4308                 case SD_BUS_TYPE_STRUCT_BEGIN:
4309                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4310                         size_t k;
4311
4312                         r = signature_element_length(t, &k);
4313                         if (r < 0)
4314                                 return r;
4315
4316                         {
4317                                 char s[k - 1];
4318                                 memcpy(s, t + 1, k - 2);
4319                                 s[k - 2] = 0;
4320
4321                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4322                                 if (r < 0)
4323                                         return r;
4324                                 if (r == 0) {
4325                                         if (n_loop <= 1)
4326                                                 return 0;
4327                                         return -ENXIO;
4328                                 }
4329                         }
4330
4331                         if (n_array == (unsigned) -1) {
4332                                 types += k - 1;
4333                                 n_struct -= k - 1;
4334                         }
4335
4336                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4337                         if (r < 0)
4338                                 return r;
4339
4340                         types = t + 1;
4341                         n_struct = k - 2;
4342                         n_array = (unsigned) -1;
4343
4344                         break;
4345                 }
4346
4347                 default:
4348                         return -EINVAL;
4349                 }
4350         }
4351
4352         return 1;
4353 }
4354
4355 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4356         va_list ap;
4357         int r;
4358
4359         assert_return(m, -EINVAL);
4360         assert_return(m->sealed, -EPERM);
4361         assert_return(types, -EINVAL);
4362
4363         va_start(ap, types);
4364         r = message_read_ap(m, types, ap);
4365         va_end(ap);
4366
4367         return r;
4368 }
4369
4370 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4371         int r;
4372
4373         assert_return(m, -EINVAL);
4374         assert_return(m->sealed, -EPERM);
4375         assert_return(types, -EINVAL);
4376
4377         if (isempty(types))
4378                 return 0;
4379
4380         switch (*types) {
4381
4382         case SD_BUS_TYPE_BYTE:
4383         case SD_BUS_TYPE_BOOLEAN:
4384         case SD_BUS_TYPE_INT16:
4385         case SD_BUS_TYPE_UINT16:
4386         case SD_BUS_TYPE_INT32:
4387         case SD_BUS_TYPE_UINT32:
4388         case SD_BUS_TYPE_INT64:
4389         case SD_BUS_TYPE_UINT64:
4390         case SD_BUS_TYPE_DOUBLE:
4391         case SD_BUS_TYPE_STRING:
4392         case SD_BUS_TYPE_OBJECT_PATH:
4393         case SD_BUS_TYPE_SIGNATURE:
4394         case SD_BUS_TYPE_UNIX_FD:
4395
4396                 r = sd_bus_message_read_basic(m, *types, NULL);
4397                 if (r <= 0)
4398                         return r;
4399
4400                 r = sd_bus_message_skip(m, types + 1);
4401                 if (r < 0)
4402                         return r;
4403
4404                 return 1;
4405
4406         case SD_BUS_TYPE_ARRAY: {
4407                 size_t k;
4408
4409                 r = signature_element_length(types + 1, &k);
4410                 if (r < 0)
4411                         return r;
4412
4413                 {
4414                         char s[k+1];
4415                         memcpy(s, types+1, k);
4416                         s[k] = 0;
4417
4418                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4419                         if (r <= 0)
4420                                 return r;
4421
4422                         for (;;) {
4423                                 r = sd_bus_message_skip(m, s);
4424                                 if (r < 0)
4425                                         return r;
4426                                 if (r == 0)
4427                                         break;
4428                         }
4429
4430                         r = sd_bus_message_exit_container(m);
4431                         if (r < 0)
4432                                 return r;
4433                 }
4434
4435                 r = sd_bus_message_skip(m, types + 1 + k);
4436                 if (r < 0)
4437                         return r;
4438
4439                 return 1;
4440         }
4441
4442         case SD_BUS_TYPE_VARIANT: {
4443                 const char *contents;
4444                 char x;
4445
4446                 r = sd_bus_message_peek_type(m, &x, &contents);
4447                 if (r <= 0)
4448                         return r;
4449
4450                 if (x != SD_BUS_TYPE_VARIANT)
4451                         return -ENXIO;
4452
4453                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4454                 if (r <= 0)
4455                         return r;
4456
4457                 r = sd_bus_message_skip(m, contents);
4458                 if (r < 0)
4459                         return r;
4460                 assert(r != 0);
4461
4462                 r = sd_bus_message_exit_container(m);
4463                 if (r < 0)
4464                         return r;
4465
4466                 r = sd_bus_message_skip(m, types + 1);
4467                 if (r < 0)
4468                         return r;
4469
4470                 return 1;
4471         }
4472
4473         case SD_BUS_TYPE_STRUCT_BEGIN:
4474         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4475                 size_t k;
4476
4477                 r = signature_element_length(types, &k);
4478                 if (r < 0)
4479                         return r;
4480
4481                 {
4482                         char s[k-1];
4483                         memcpy(s, types+1, k-2);
4484                         s[k-2] = 0;
4485
4486                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4487                         if (r <= 0)
4488                                 return r;
4489
4490                         r = sd_bus_message_skip(m, s);
4491                         if (r < 0)
4492                                 return r;
4493                         assert(r != 0);
4494
4495                         r = sd_bus_message_exit_container(m);
4496                         if (r < 0)
4497                                 return r;
4498                 }
4499
4500                 r = sd_bus_message_skip(m, types + k);
4501                 if (r < 0)
4502                         return r;
4503
4504                 return 1;
4505         }
4506
4507         default:
4508                 return -EINVAL;
4509         }
4510 }
4511
4512 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4513                                        char type,
4514                                        const void **ptr,
4515                                        size_t *size) {
4516         struct bus_container *c;
4517         void *p;
4518         size_t sz;
4519         ssize_t align;
4520         int r;
4521
4522         assert_return(m, -EINVAL);
4523         assert_return(m->sealed, -EPERM);
4524         assert_return(bus_type_is_trivial(type), -EINVAL);
4525         assert_return(ptr, -EINVAL);
4526         assert_return(size, -EINVAL);
4527         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4528
4529         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4530         if (r <= 0)
4531                 return r;
4532
4533         c = message_get_container(m);
4534
4535         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4536                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4537                 if (align < 0)
4538                         return align;
4539
4540                 sz = c->end - c->begin;
4541         } else {
4542                 align = bus_type_get_alignment(type);
4543                 if (align < 0)
4544                         return align;
4545
4546                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4547         }
4548
4549         if (sz == 0)
4550                 /* Zero length array, let's return some aligned
4551                  * pointer that is not NULL */
4552                 p = (uint8_t*) NULL + align;
4553         else {
4554                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4555                 if (r < 0)
4556                         goto fail;
4557         }
4558
4559         r = sd_bus_message_exit_container(m);
4560         if (r < 0)
4561                 goto fail;
4562
4563         *ptr = (const void*) p;
4564         *size = sz;
4565
4566         return 1;
4567
4568 fail:
4569         message_quit_container(m);
4570         return r;
4571 }
4572
4573 static int message_peek_fields(
4574                 sd_bus_message *m,
4575                 size_t *rindex,
4576                 size_t align,
4577                 size_t nbytes,
4578                 void **ret) {
4579
4580         assert(m);
4581         assert(rindex);
4582         assert(align > 0);
4583
4584         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4585 }
4586
4587 static int message_peek_field_uint32(
4588                 sd_bus_message *m,
4589                 size_t *ri,
4590                 size_t item_size,
4591                 uint32_t *ret) {
4592
4593         int r;
4594         void *q;
4595
4596         assert(m);
4597         assert(ri);
4598
4599         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4600                 return -EBADMSG;
4601
4602         /* identical for gvariant and dbus1 */
4603
4604         r = message_peek_fields(m, ri, 4, 4, &q);
4605         if (r < 0)
4606                 return r;
4607
4608         if (ret)
4609                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4610
4611         return 0;
4612 }
4613
4614 static int message_peek_field_string(
4615                 sd_bus_message *m,
4616                 bool (*validate)(const char *p),
4617                 size_t *ri,
4618                 size_t item_size,
4619                 const char **ret) {
4620
4621         uint32_t l;
4622         int r;
4623         void *q;
4624
4625         assert(m);
4626         assert(ri);
4627
4628         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4629
4630                 if (item_size <= 0)
4631                         return -EBADMSG;
4632
4633                 r = message_peek_fields(m, ri, 1, item_size, &q);
4634                 if (r < 0)
4635                         return r;
4636
4637                 l = item_size - 1;
4638         } else {
4639                 r = message_peek_field_uint32(m, ri, 4, &l);
4640                 if (r < 0)
4641                         return r;
4642
4643                 r = message_peek_fields(m, ri, 1, l+1, &q);
4644                 if (r < 0)
4645                         return r;
4646         }
4647
4648         if (validate) {
4649                 if (!validate_nul(q, l))
4650                         return -EBADMSG;
4651
4652                 if (!validate(q))
4653                         return -EBADMSG;
4654         } else {
4655                 if (!validate_string(q, l))
4656                         return -EBADMSG;
4657         }
4658
4659         if (ret)
4660                 *ret = q;
4661
4662         return 0;
4663 }
4664
4665 static int message_peek_field_signature(
4666                 sd_bus_message *m,
4667                 size_t *ri,
4668                 size_t item_size,
4669                 const char **ret) {
4670
4671         size_t l;
4672         int r;
4673         void *q;
4674
4675         assert(m);
4676         assert(ri);
4677
4678         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4679
4680                 if (item_size <= 0)
4681                         return -EBADMSG;
4682
4683                 r = message_peek_fields(m, ri, 1, item_size, &q);
4684                 if (r < 0)
4685                         return r;
4686
4687                 l = item_size - 1;
4688         } else {
4689                 r = message_peek_fields(m, ri, 1, 1, &q);
4690                 if (r < 0)
4691                         return r;
4692
4693                 l = *(uint8_t*) q;
4694                 r = message_peek_fields(m, ri, 1, l+1, &q);
4695                 if (r < 0)
4696                         return r;
4697         }
4698
4699         if (!validate_signature(q, l))
4700                 return -EBADMSG;
4701
4702         if (ret)
4703                 *ret = q;
4704
4705         return 0;
4706 }
4707
4708 static int message_skip_fields(
4709                 sd_bus_message *m,
4710                 size_t *ri,
4711                 uint32_t array_size,
4712                 const char **signature) {
4713
4714         size_t original_index;
4715         int r;
4716
4717         assert(m);
4718         assert(ri);
4719         assert(signature);
4720         assert(!BUS_MESSAGE_IS_GVARIANT(m));
4721
4722         original_index = *ri;
4723
4724         for (;;) {
4725                 char t;
4726                 size_t l;
4727
4728                 if (array_size != (uint32_t) -1 &&
4729                     array_size <= *ri - original_index)
4730                         return 0;
4731
4732                 t = **signature;
4733                 if (!t)
4734                         return 0;
4735
4736                 if (t == SD_BUS_TYPE_STRING) {
4737
4738                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
4739                         if (r < 0)
4740                                 return r;
4741
4742                         (*signature)++;
4743
4744                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4745
4746                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4747                         if (r < 0)
4748                                 return r;
4749
4750                         (*signature)++;
4751
4752                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4753
4754                         r = message_peek_field_signature(m, ri, 0, NULL);
4755                         if (r < 0)
4756                                 return r;
4757
4758                         (*signature)++;
4759
4760                 } else if (bus_type_is_basic(t)) {
4761                         ssize_t align, k;
4762
4763                         align = bus_type_get_alignment(t);
4764                         k = bus_type_get_size(t);
4765                         assert(align > 0 && k > 0);
4766
4767                         r = message_peek_fields(m, ri, align, k, NULL);
4768                         if (r < 0)
4769                                 return r;
4770
4771                         (*signature)++;
4772
4773                 } else if (t == SD_BUS_TYPE_ARRAY) {
4774
4775                         r = signature_element_length(*signature+1, &l);
4776                         if (r < 0)
4777                                 return r;
4778
4779                         assert(l >= 1);
4780                         {
4781                                 char sig[l-1], *s;
4782                                 uint32_t nas;
4783                                 int alignment;
4784
4785                                 strncpy(sig, *signature + 1, l-1);
4786                                 s = sig;
4787
4788                                 alignment = bus_type_get_alignment(sig[0]);
4789                                 if (alignment < 0)
4790                                         return alignment;
4791
4792                                 r = message_peek_field_uint32(m, ri, 0, &nas);
4793                                 if (r < 0)
4794                                         return r;
4795                                 if (nas > BUS_ARRAY_MAX_SIZE)
4796                                         return -EBADMSG;
4797
4798                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
4799                                 if (r < 0)
4800                                         return r;
4801
4802                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
4803                                 if (r < 0)
4804                                         return r;
4805                         }
4806
4807                         (*signature) += 1 + l;
4808
4809                 } else if (t == SD_BUS_TYPE_VARIANT) {
4810                         const char *s;
4811
4812                         r = message_peek_field_signature(m, ri, 0, &s);
4813                         if (r < 0)
4814                                 return r;
4815
4816                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4817                         if (r < 0)
4818                                 return r;
4819
4820                         (*signature)++;
4821
4822                 } else if (t == SD_BUS_TYPE_STRUCT ||
4823                            t == SD_BUS_TYPE_DICT_ENTRY) {
4824
4825                         r = signature_element_length(*signature, &l);
4826                         if (r < 0)
4827                                 return r;
4828
4829                         assert(l >= 2);
4830                         {
4831                                 char sig[l-1], *s;
4832                                 strncpy(sig, *signature + 1, l-1);
4833                                 s = sig;
4834
4835                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4836                                 if (r < 0)
4837                                         return r;
4838                         }
4839
4840                         *signature += l;
4841                 } else
4842                         return -EINVAL;
4843         }
4844 }
4845
4846 int bus_message_parse_fields(sd_bus_message *m) {
4847         size_t ri;
4848         int r;
4849         uint32_t unix_fds = 0;
4850         void *offsets = NULL;
4851         unsigned n_offsets = 0;
4852         size_t sz = 0;
4853         unsigned i = 0;
4854
4855         assert(m);
4856
4857         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4858                 void *q;
4859
4860                 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4861                 if (sz > 0) {
4862                         size_t framing;
4863
4864                         ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4865                         r = message_peek_fields(m, &ri, 1, sz, &q);
4866                         if (r < 0)
4867                                 return r;
4868
4869                         framing = read_word_le(q, sz);
4870                         if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4871                                 return -EBADMSG;
4872                         if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4873                                 return -EBADMSG;
4874
4875                         ri = framing;
4876                         r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4877                         if (r < 0)
4878                                 return r;
4879
4880                         n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4881                 }
4882         }
4883
4884         ri = 0;
4885         while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4886                 _cleanup_free_ char *sig = NULL;
4887                 const char *signature;
4888                 uint8_t *header;
4889                 size_t item_size = (size_t) -1;
4890
4891                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4892                         if (i >= n_offsets)
4893                                 break;
4894
4895                         if (i == 0)
4896                                 ri = 0;
4897                         else
4898                                 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
4899                 }
4900
4901                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4902                 if (r < 0)
4903                         return r;
4904
4905                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4906                         size_t where, end;
4907                         char *b;
4908                         void *q;
4909
4910                         end = read_word_le((uint8_t*) offsets + i*sz, sz);
4911
4912                         if (end < ri)
4913                                 return -EBADMSG;
4914
4915                         where = ri = ALIGN_TO(ri, 8);
4916                         item_size = end - ri;
4917                         r = message_peek_fields(m, &where, 1, item_size, &q);
4918                         if (r < 0)
4919                                 return r;
4920
4921                         b = memrchr(q, 0, item_size);
4922                         if (!b)
4923                                 return -EBADMSG;
4924
4925                         sig = strndup(b+1, item_size - (b+1-(char*) q));
4926                         if (!sig)
4927                                 return -ENOMEM;
4928
4929                         signature = sig;
4930                         item_size = b - (char*) q;
4931                 } else {
4932                         r = message_peek_field_signature(m, &ri, 0, &signature);
4933                         if (r < 0)
4934                                 return r;
4935                 }
4936
4937                 switch (*header) {
4938                 case _BUS_MESSAGE_HEADER_INVALID:
4939                         return -EBADMSG;
4940
4941                 case BUS_MESSAGE_HEADER_PATH:
4942
4943                         if (m->path)
4944                                 return -EBADMSG;
4945
4946                         if (!streq(signature, "o"))
4947                                 return -EBADMSG;
4948
4949                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
4950                         break;
4951
4952                 case BUS_MESSAGE_HEADER_INTERFACE:
4953
4954                         if (m->interface)
4955                                 return -EBADMSG;
4956
4957                         if (!streq(signature, "s"))
4958                                 return -EBADMSG;
4959
4960                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
4961                         break;
4962
4963                 case BUS_MESSAGE_HEADER_MEMBER:
4964
4965                         if (m->member)
4966                                 return -EBADMSG;
4967
4968                         if (!streq(signature, "s"))
4969                                 return -EBADMSG;
4970
4971                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
4972                         break;
4973
4974                 case BUS_MESSAGE_HEADER_ERROR_NAME:
4975
4976                         if (m->error.name)
4977                                 return -EBADMSG;
4978
4979                         if (!streq(signature, "s"))
4980                                 return -EBADMSG;
4981
4982                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
4983                         if (r >= 0)
4984                                 m->error._need_free = -1;
4985
4986                         break;
4987
4988                 case BUS_MESSAGE_HEADER_DESTINATION:
4989
4990                         if (m->destination)
4991                                 return -EBADMSG;
4992
4993                         if (!streq(signature, "s"))
4994                                 return -EBADMSG;
4995
4996                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
4997                         break;
4998
4999                 case BUS_MESSAGE_HEADER_SENDER:
5000
5001                         if (m->sender)
5002                                 return -EBADMSG;
5003
5004                         if (!streq(signature, "s"))
5005                                 return -EBADMSG;
5006
5007                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5008
5009                         if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
5010                                 m->creds.unique_name = (char*) m->sender;
5011                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5012                         }
5013
5014                         break;
5015
5016
5017                 case BUS_MESSAGE_HEADER_SIGNATURE: {
5018                         const char *s;
5019                         char *c;
5020
5021                         if (m->root_container.signature)
5022                                 return -EBADMSG;
5023
5024                         if (!streq(signature, "g"))
5025                                 return -EBADMSG;
5026
5027                         r = message_peek_field_signature(m, &ri, item_size, &s);
5028                         if (r < 0)
5029                                 return r;
5030
5031                         c = strdup(s);
5032                         if (!c)
5033                                 return -ENOMEM;
5034
5035                         free(m->root_container.signature);
5036                         m->root_container.signature = c;
5037                         break;
5038                 }
5039
5040                 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5041                         if (m->reply_serial != 0)
5042                                 return -EBADMSG;
5043
5044                         if (!streq(signature, "u"))
5045                                 return -EBADMSG;
5046
5047                         r = message_peek_field_uint32(m, &ri, item_size, &m->reply_serial);
5048                         if (r < 0)
5049                                 return r;
5050
5051                         if (m->reply_serial == 0)
5052                                 return -EBADMSG;
5053
5054                         break;
5055
5056                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5057                         if (unix_fds != 0)
5058                                 return -EBADMSG;
5059
5060                         if (!streq(signature, "u"))
5061                                 return -EBADMSG;
5062
5063                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5064                         if (r < 0)
5065                                 return -EBADMSG;
5066
5067                         if (unix_fds == 0)
5068                                 return -EBADMSG;
5069
5070                         break;
5071
5072                 default:
5073                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5074                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5075                 }
5076
5077                 if (r < 0)
5078                         return r;
5079
5080                 i++;
5081         }
5082
5083         if (m->n_fds != unix_fds)
5084                 return -EBADMSG;
5085
5086         switch (m->header->type) {
5087
5088         case SD_BUS_MESSAGE_SIGNAL:
5089                 if (!m->path || !m->interface || !m->member)
5090                         return -EBADMSG;
5091                 break;
5092
5093         case SD_BUS_MESSAGE_METHOD_CALL:
5094
5095                 if (!m->path || !m->member)
5096                         return -EBADMSG;
5097
5098                 break;
5099
5100         case SD_BUS_MESSAGE_METHOD_RETURN:
5101
5102                 if (m->reply_serial == 0)
5103                         return -EBADMSG;
5104                 break;
5105
5106         case SD_BUS_MESSAGE_METHOD_ERROR:
5107
5108                 if (m->reply_serial == 0 || !m->error.name)
5109                         return -EBADMSG;
5110                 break;
5111         }
5112
5113         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5114
5115         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5116                 r = build_struct_offsets(
5117                                 m,
5118                                 m->root_container.signature,
5119                                 BUS_MESSAGE_BODY_SIZE(m),
5120                                 &m->root_container.item_size,
5121                                 &m->root_container.offsets,
5122                                 &m->root_container.n_offsets);
5123                 if (r < 0)
5124                         return r;
5125         }
5126
5127         /* Try to read the error message, but if we can't it's a non-issue */
5128         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5129                 sd_bus_message_read(m, "s", &m->error.message);
5130
5131         return 0;
5132 }
5133
5134 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5135         assert_return(m, -EINVAL);
5136         assert_return(destination, -EINVAL);
5137         assert_return(!m->sealed, -EPERM);
5138         assert_return(!m->destination, -EEXIST);
5139
5140         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5141 }
5142
5143 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5144         size_t total;
5145         void *p, *e;
5146         unsigned i;
5147         struct bus_body_part *part;
5148
5149         assert(m);
5150         assert(buffer);
5151         assert(sz);
5152
5153         total = BUS_MESSAGE_SIZE(m);
5154
5155         p = malloc(total);
5156         if (!p)
5157                 return -ENOMEM;
5158
5159         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5160         MESSAGE_FOREACH_PART(part, i, m)
5161                 e = mempcpy(e, part->data, part->size);
5162
5163         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5164
5165         *buffer = p;
5166         *sz = total;
5167
5168         return 0;
5169 }
5170
5171 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5172         int r;
5173
5174         assert(m);
5175         assert(l);
5176
5177         r = sd_bus_message_enter_container(m, 'a', "s");
5178         if (r <= 0)
5179                 return r;
5180
5181         for (;;) {
5182                 const char *s;
5183
5184                 r = sd_bus_message_read_basic(m, 's', &s);
5185                 if (r < 0)
5186                         return r;
5187                 if (r == 0)
5188                         break;
5189
5190                 r = strv_extend(l, s);
5191                 if (r < 0)
5192                         return r;
5193         }
5194
5195         r = sd_bus_message_exit_container(m);
5196         if (r < 0)
5197                 return r;
5198
5199         return 1;
5200 }
5201
5202 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5203         char **strv = NULL;
5204         int r;
5205
5206         assert_return(m, -EINVAL);
5207         assert_return(m->sealed, -EPERM);
5208         assert_return(l, -EINVAL);
5209
5210         r = bus_message_read_strv_extend(m, &strv);
5211         if (r <= 0) {
5212                 strv_free(strv);
5213                 return r;
5214         }
5215
5216         *l = strv;
5217         return 1;
5218 }
5219
5220 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
5221         int r;
5222         const char *t = NULL;
5223         unsigned j;
5224
5225         assert(m);
5226
5227         r = sd_bus_message_rewind(m, true);
5228         if (r < 0)
5229                 return NULL;
5230
5231         for (j = 0; j <= i; j++) {
5232                 char type;
5233
5234                 r = sd_bus_message_peek_type(m, &type, NULL);
5235                 if (r < 0)
5236                         return NULL;
5237
5238                 if (type != SD_BUS_TYPE_STRING &&
5239                     type != SD_BUS_TYPE_OBJECT_PATH &&
5240                     type != SD_BUS_TYPE_SIGNATURE)
5241                         return NULL;
5242
5243                 r = sd_bus_message_read_basic(m, type, &t);
5244                 if (r < 0)
5245                         return NULL;
5246         }
5247
5248         return t;
5249 }
5250
5251 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5252         size_t full;
5253
5254         assert(h);
5255         assert(size);
5256
5257         if (size < sizeof(struct bus_header))
5258                 return false;
5259
5260         full = sizeof(struct bus_header) +
5261                 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5262
5263         return size >= full;
5264 }
5265
5266 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5267         size_t fs, bs;
5268
5269         assert(h);
5270         assert(sum);
5271
5272         if (h->endian == BUS_NATIVE_ENDIAN) {
5273                 fs = h->fields_size;
5274                 bs = h->body_size;
5275         } else if (h->endian == BUS_REVERSE_ENDIAN) {
5276                 fs = bswap_32(h->fields_size);
5277                 bs = bswap_32(h->body_size);
5278         } else
5279                 return -EBADMSG;
5280
5281         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5282         return 0;
5283 }
5284
5285 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5286         assert_return(m, -EINVAL);
5287
5288         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5289                 return 0;
5290
5291         return sd_bus_error_get_errno(&m->error);
5292 }
5293
5294 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5295         struct bus_container *c;
5296
5297         assert_return(m, NULL);
5298
5299         c = complete ? &m->root_container : message_get_container(m);
5300         return strempty(c->signature);
5301 }
5302
5303 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5304         bool done_something = false;
5305         int r;
5306
5307         assert_return(m, -EINVAL);
5308         assert_return(source, -EINVAL);
5309         assert_return(!m->sealed, -EPERM);
5310         assert_return(source->sealed, -EPERM);
5311
5312         do {
5313                 const char *contents;
5314                 char type;
5315                 union {
5316                         uint8_t u8;
5317                         uint16_t u16;
5318                         int16_t s16;
5319                         uint32_t u32;
5320                         int32_t s32;
5321                         uint64_t u64;
5322                         int64_t s64;
5323                         double d64;
5324                         const char *string;
5325                         int i;
5326                 } basic;
5327
5328                 r = sd_bus_message_peek_type(source, &type, &contents);
5329                 if (r < 0)
5330                         return r;
5331                 if (r == 0)
5332                         break;
5333
5334                 done_something = true;
5335
5336                 if (bus_type_is_container(type) > 0) {
5337
5338                         r = sd_bus_message_enter_container(source, type, contents);
5339                         if (r < 0)
5340                                 return r;
5341
5342                         r = sd_bus_message_open_container(m, type, contents);
5343                         if (r < 0)
5344                                 return r;
5345
5346                         r = sd_bus_message_copy(m, source, true);
5347                         if (r < 0)
5348                                 return r;
5349
5350                         r = sd_bus_message_close_container(m);
5351                         if (r < 0)
5352                                 return r;
5353
5354                         r = sd_bus_message_exit_container(source);
5355                         if (r < 0)
5356                                 return r;
5357
5358                         continue;
5359                 }
5360
5361                 r = sd_bus_message_read_basic(source, type, &basic);
5362                 if (r < 0)
5363                         return r;
5364
5365                 assert(r > 0);
5366
5367                 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5368                     type == SD_BUS_TYPE_SIGNATURE ||
5369                     type == SD_BUS_TYPE_STRING)
5370                         r = sd_bus_message_append_basic(m, type, basic.string);
5371                 else
5372                         r = sd_bus_message_append_basic(m, type, &basic);
5373
5374                 if (r < 0)
5375                         return r;
5376
5377         } while (all);
5378
5379         return done_something;
5380 }
5381
5382 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5383         const char *c;
5384         char t;
5385         int r;
5386
5387         assert_return(m, -EINVAL);
5388         assert_return(m->sealed, -EPERM);
5389         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5390         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5391         assert_return(type || contents, -EINVAL);
5392         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5393
5394         r = sd_bus_message_peek_type(m, &t, &c);
5395         if (r <= 0)
5396                 return r;
5397
5398         if (type != 0 && type != t)
5399                 return 0;
5400
5401         if (contents && !streq_ptr(contents, c))
5402                 return 0;
5403
5404         return 1;
5405 }
5406
5407 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5408         assert_return(m, NULL);
5409
5410         return m->bus;
5411 }