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