chiark / gitweb /
264a2f63f16b3ea4d5eb4623c5de7be49b81d385
[elogind.git] / src / libsystemd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "cgroup-util.h"
31
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-type.h"
36 #include "bus-signature.h"
37
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
39
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
41
42         if (p == NULL)
43                 return NULL;
44
45         if (old_base == new_base)
46                 return (void*) p;
47
48         if ((uint8_t*) p < (uint8_t*) old_base)
49                 return (void*) p;
50
51         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
52                 return (void*) p;
53
54         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
55 }
56
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
58         assert(m);
59         assert(part);
60
61         if (part->memfd >= 0) {
62                 /* If we can reuse the memfd, try that. For that it
63                  * can't be sealed yet. */
64
65                 if (!part->sealed)
66                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
67                 else {
68                         if (part->mapped > 0)
69                                 assert_se(munmap(part->data, part->mapped) == 0);
70
71                         close_nointr_nofail(part->memfd);
72                 }
73
74         } else if (part->munmap_this)
75                 munmap(part->data, part->mapped);
76         else if (part->free_this)
77                 free(part->data);
78
79         if (part != &m->body)
80                 free(part);
81 }
82
83 static void message_reset_parts(sd_bus_message *m) {
84         struct bus_body_part *part;
85
86         assert(m);
87
88         part = &m->body;
89         while (m->n_body_parts > 0) {
90                 struct bus_body_part *next = part->next;
91                 message_free_part(m, part);
92                 part = next;
93                 m->n_body_parts--;
94         }
95
96         m->body_end = NULL;
97
98         m->cached_rindex_part = NULL;
99         m->cached_rindex_part_begin = 0;
100 }
101
102 static void message_reset_containers(sd_bus_message *m) {
103         unsigned i;
104
105         assert(m);
106
107         for (i = 0; i < m->n_containers; i++)
108                 free(m->containers[i].signature);
109
110         free(m->containers);
111         m->containers = NULL;
112
113         m->n_containers = 0;
114         m->root_container.index = 0;
115 }
116
117 static void message_free(sd_bus_message *m) {
118         assert(m);
119
120         if (m->free_header)
121                 free(m->header);
122
123         message_reset_parts(m);
124
125         if (m->free_kdbus)
126                 free(m->kdbus);
127
128         if (m->release_kdbus) {
129                 uint64_t off;
130
131                 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132                 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
133         }
134
135         if (m->bus)
136                 sd_bus_unref(m->bus);
137
138         if (m->free_fds) {
139                 close_many(m->fds, m->n_fds);
140                 free(m->fds);
141         }
142
143         if (m->iovec != m->iovec_fixed)
144                 free(m->iovec);
145
146         free(m->cmdline_array);
147
148         message_reset_containers(m);
149         free(m->root_container.signature);
150
151         free(m->peeked_signature);
152
153         free(m->unit);
154         free(m->user_unit);
155         free(m->session);
156         free(m);
157 }
158
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
160         void *op, *np;
161         size_t old_size, new_size, start;
162
163         assert(m);
164
165         if (m->poisoned)
166                 return NULL;
167
168         old_size = sizeof(struct bus_header) + m->header->fields_size;
169         start = ALIGN_TO(old_size, align);
170         new_size = start + sz;
171
172         if (old_size == new_size)
173                 return (uint8_t*) m->header + old_size;
174
175         if (new_size > (size_t) ((uint32_t) -1))
176                 goto poison;
177
178         if (m->free_header) {
179                 np = realloc(m->header, ALIGN8(new_size));
180                 if (!np)
181                         goto poison;
182         } else {
183                 /* Initially, the header is allocated as part of of
184                  * the sd_bus_message itself, let's replace it by
185                  * dynamic data */
186
187                 np = malloc(ALIGN8(new_size));
188                 if (!np)
189                         goto poison;
190
191                 memcpy(np, m->header, sizeof(struct bus_header));
192         }
193
194         /* Zero out padding */
195         if (start > old_size)
196                 memset((uint8_t*) np + old_size, 0, start - old_size);
197
198         op = m->header;
199         m->header = np;
200         m->header->fields_size = new_size - sizeof(struct bus_header);
201
202         /* Adjust quick access pointers */
203         m->path = adjust_pointer(m->path, op, old_size, m->header);
204         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205         m->member = adjust_pointer(m->member, op, old_size, m->header);
206         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
209
210         m->free_header = true;
211
212         return (uint8_t*) np + start;
213
214 poison:
215         m->poisoned = true;
216         return NULL;
217 }
218
219 static int message_append_field_string(
220                 sd_bus_message *m,
221                 uint8_t h,
222                 char type,
223                 const char *s,
224                 const char **ret) {
225
226         size_t l;
227         uint8_t *p;
228
229         assert(m);
230
231         l = strlen(s);
232         if (l > (size_t) (uint32_t) -1)
233                 return -EINVAL;
234
235         /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
236         p = message_extend_fields(m, 8, 4 + 4 + l + 1);
237         if (!p)
238                 return -ENOMEM;
239
240         p[0] = h;
241         p[1] = 1;
242         p[2] = type;
243         p[3] = 0;
244
245         ((uint32_t*) p)[1] = l;
246         memcpy(p + 8, s, l + 1);
247
248         if (ret)
249                 *ret = (char*) p + 8;
250
251         return 0;
252 }
253
254 static int message_append_field_signature(
255                 sd_bus_message *m,
256                 uint8_t h,
257                 const char *s,
258                 const char **ret) {
259
260         size_t l;
261         uint8_t *p;
262
263         assert(m);
264
265         l = strlen(s);
266         if (l > 255)
267                 return -EINVAL;
268
269         /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
270         p = message_extend_fields(m, 8, 4 + 1 + l + 1);
271         if (!p)
272                 return -ENOMEM;
273
274         p[0] = h;
275         p[1] = 1;
276         p[2] = SD_BUS_TYPE_SIGNATURE;
277         p[3] = 0;
278         p[4] = l;
279         memcpy(p + 5, s, l + 1);
280
281         if (ret)
282                 *ret = (const char*) p + 5;
283
284         return 0;
285 }
286
287 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
288         uint8_t *p;
289
290         assert(m);
291
292         /* field id byte + signature length + signature 'u' + NUL + value */
293         p = message_extend_fields(m, 8, 4 + 4);
294         if (!p)
295                 return -ENOMEM;
296
297         p[0] = h;
298         p[1] = 1;
299         p[2] = SD_BUS_TYPE_UINT32;
300         p[3] = 0;
301
302         ((uint32_t*) p)[1] = x;
303
304         return 0;
305 }
306
307 int bus_message_from_header(
308                 void *buffer,
309                 size_t length,
310                 int *fds,
311                 unsigned n_fds,
312                 const struct ucred *ucred,
313                 const char *label,
314                 size_t extra,
315                 sd_bus_message **ret) {
316
317         sd_bus_message *m;
318         struct bus_header *h;
319         size_t a, label_sz;
320
321         assert(buffer || length <= 0);
322         assert(fds || n_fds <= 0);
323         assert(ret);
324
325         if (length < sizeof(struct bus_header))
326                 return -EBADMSG;
327
328         h = buffer;
329         if (h->version != 1)
330                 return -EBADMSG;
331
332         if (h->serial == 0)
333                 return -EBADMSG;
334
335         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
336                 return -EBADMSG;
337
338         if (h->endian != SD_BUS_LITTLE_ENDIAN &&
339             h->endian != SD_BUS_BIG_ENDIAN)
340                 return -EBADMSG;
341
342         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
343
344         if (label) {
345                 label_sz = strlen(label);
346                 a += label_sz + 1;
347         }
348
349         m = malloc0(a);
350         if (!m)
351                 return -ENOMEM;
352
353         m->n_ref = 1;
354         m->sealed = true;
355         m->header = h;
356         m->fds = fds;
357         m->n_fds = n_fds;
358
359         if (ucred) {
360                 m->uid = ucred->uid;
361                 m->pid = ucred->pid;
362                 m->gid = ucred->gid;
363                 m->uid_valid = m->gid_valid = true;
364         }
365
366         if (label) {
367                 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
368                 memcpy(m->label, label, label_sz + 1);
369         }
370
371         *ret = m;
372         return 0;
373 }
374
375 int bus_message_from_malloc(
376                 void *buffer,
377                 size_t length,
378                 int *fds,
379                 unsigned n_fds,
380                 const struct ucred *ucred,
381                 const char *label,
382                 sd_bus_message **ret) {
383
384         sd_bus_message *m;
385         int r;
386
387         r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
388         if (r < 0)
389                 return r;
390
391         if (length != BUS_MESSAGE_SIZE(m)) {
392                 r = -EBADMSG;
393                 goto fail;
394         }
395
396         m->n_body_parts = 1;
397         m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398         m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
399         m->body.sealed = true;
400         m->body.memfd = -1;
401
402         m->n_iovec = 1;
403         m->iovec = m->iovec_fixed;
404         m->iovec[0].iov_base = buffer;
405         m->iovec[0].iov_len = length;
406
407         r = bus_message_parse_fields(m);
408         if (r < 0)
409                 goto fail;
410
411         /* We take possession of the memory and fds now */
412         m->free_header = true;
413         m->free_fds = true;
414
415         *ret = m;
416         return 0;
417
418 fail:
419         message_free(m);
420         return r;
421 }
422
423 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
424         sd_bus_message *m;
425
426         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
427         if (!m)
428                 return NULL;
429
430         m->n_ref = 1;
431         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
432         m->header->endian = SD_BUS_NATIVE_ENDIAN;
433         m->header->type = type;
434         m->header->version = bus ? bus->message_version : 1;
435         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
436
437         if (bus)
438                 m->bus = sd_bus_ref(bus);
439
440         return m;
441 }
442
443 int sd_bus_message_new_signal(
444                 sd_bus *bus,
445                 const char *path,
446                 const char *interface,
447                 const char *member,
448                 sd_bus_message **m) {
449
450         sd_bus_message *t;
451         int r;
452
453         if (!path)
454                 return -EINVAL;
455         if (!interface)
456                 return -EINVAL;
457         if (!member)
458                 return -EINVAL;
459         if (!m)
460                 return -EINVAL;
461         if (bus && bus->state == BUS_UNSET)
462                 return -ENOTCONN;
463
464         t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
465         if (!t)
466                 return -ENOMEM;
467
468         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
469
470         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
471         if (r < 0)
472                 goto fail;
473         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
474         if (r < 0)
475                 goto fail;
476         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
477         if (r < 0)
478                 goto fail;
479
480         *m = t;
481         return 0;
482
483 fail:
484         sd_bus_message_unref(t);
485         return r;
486 }
487
488 int sd_bus_message_new_method_call(
489                 sd_bus *bus,
490                 const char *destination,
491                 const char *path,
492                 const char *interface,
493                 const char *member,
494                 sd_bus_message **m) {
495
496         sd_bus_message *t;
497         int r;
498
499         if (destination && !service_name_is_valid(destination))
500                 return -EINVAL;
501         if (!object_path_is_valid(path))
502                 return -EINVAL;
503         if (interface && !interface_name_is_valid(interface))
504                 return -EINVAL;
505         if (!member_name_is_valid(member))
506                 return -EINVAL;
507         if (!m)
508                 return -EINVAL;
509         if (bus && bus->state == BUS_UNSET)
510                 return -ENOTCONN;
511
512         t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
513         if (!t)
514                 return -ENOMEM;
515
516         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
517         if (r < 0)
518                 goto fail;
519         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
520         if (r < 0)
521                 goto fail;
522
523         if (interface) {
524                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
525                 if (r < 0)
526                         goto fail;
527         }
528
529         if (destination) {
530                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
531                 if (r < 0)
532                         goto fail;
533         }
534
535         *m = t;
536         return 0;
537
538 fail:
539         message_free(t);
540         return r;
541 }
542
543 static int message_new_reply(
544                 sd_bus *bus,
545                 sd_bus_message *call,
546                 uint8_t type,
547                 sd_bus_message **m) {
548
549         sd_bus_message *t;
550         int r;
551
552         if (!call)
553                 return -EINVAL;
554         if (!call->sealed)
555                 return -EPERM;
556         if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
557                 return -EINVAL;
558         if (!m)
559                 return -EINVAL;
560         if (bus && bus->state == BUS_UNSET)
561                 return -ENOTCONN;
562
563         t = message_new(bus, type);
564         if (!t)
565                 return -ENOMEM;
566
567         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
568         t->reply_serial = BUS_MESSAGE_SERIAL(call);
569
570         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
571         if (r < 0)
572                 goto fail;
573
574         if (call->sender) {
575                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
576                 if (r < 0)
577                         goto fail;
578         }
579
580         t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
581
582         *m = t;
583         return 0;
584
585 fail:
586         message_free(t);
587         return r;
588 }
589
590 int sd_bus_message_new_method_return(
591                 sd_bus *bus,
592                 sd_bus_message *call,
593                 sd_bus_message **m) {
594
595         return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
596 }
597
598 int sd_bus_message_new_method_error(
599                 sd_bus *bus,
600                 sd_bus_message *call,
601                 const sd_bus_error *e,
602                 sd_bus_message **m) {
603
604         sd_bus_message *t;
605         int r;
606
607         if (!sd_bus_error_is_set(e))
608                 return -EINVAL;
609         if (!m)
610                 return -EINVAL;
611
612         r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
613         if (r < 0)
614                 return r;
615
616         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
617         if (r < 0)
618                 goto fail;
619
620         if (e->message) {
621                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
622                 if (r < 0)
623                         goto fail;
624         }
625
626         *m = t;
627         return 0;
628
629 fail:
630         message_free(t);
631         return r;
632 }
633
634 int sd_bus_message_new_method_errorf(
635                 sd_bus *bus,
636                 sd_bus_message *call,
637                 sd_bus_message **m,
638                 const char *name,
639                 const char *format,
640                 ...) {
641
642         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
643         sd_bus_message *t;
644         va_list ap;
645         int r;
646
647         if (!name)
648                 return -EINVAL;
649         if (!m)
650                 return -EINVAL;
651
652         r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
653         if (r < 0)
654                 return r;
655
656         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, name, &t->error.name);
657         if (r < 0)
658                 goto fail;
659
660         if (format) {
661                 _cleanup_free_ char *message = NULL;
662
663                 va_start(ap, format);
664                 r = vasprintf(&message, format, ap);
665                 va_end(ap);
666
667                 if (r < 0) {
668                         r = -ENOMEM;
669                         goto fail;
670                 }
671
672                 r = message_append_basic(t, SD_BUS_TYPE_STRING, message, (const void**) &t->error.message);
673                 if (r < 0)
674                         goto fail;
675         }
676
677         *m = t;
678         return 0;
679
680 fail:
681         message_free(t);
682         return r;
683 }
684
685 int bus_message_new_synthetic_error(
686                 sd_bus *bus,
687                 uint64_t serial,
688                 const sd_bus_error *e,
689                 sd_bus_message **m) {
690
691         sd_bus_message *t;
692         int r;
693
694         assert(sd_bus_error_is_set(e));
695         assert(m);
696
697         t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR);
698         if (!t)
699                 return -ENOMEM;
700
701         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
702         t->reply_serial = serial;
703
704         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
705         if (r < 0)
706                 goto fail;
707
708         if (bus && bus->unique_name) {
709                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
710                 if (r < 0)
711                         goto fail;
712         }
713
714         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
715         if (r < 0)
716                 goto fail;
717
718         if (e->message) {
719                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
720                 if (r < 0)
721                         goto fail;
722         }
723
724         *m = t;
725         return 0;
726
727 fail:
728         message_free(t);
729         return r;
730 }
731
732 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
733         if (!m)
734                 return NULL;
735
736         assert(m->n_ref > 0);
737         m->n_ref++;
738
739         return m;
740 }
741
742 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
743         if (!m)
744                 return NULL;
745
746         assert(m->n_ref > 0);
747         m->n_ref--;
748
749         if (m->n_ref <= 0)
750                 message_free(m);
751
752         return NULL;
753 }
754
755 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
756         if (!m)
757                 return -EINVAL;
758         if (!type)
759                 return -EINVAL;
760
761         *type = m->header->type;
762         return 0;
763 }
764
765 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
766         if (!m)
767                 return -EINVAL;
768         if (!serial)
769                 return -EINVAL;
770         if (m->header->serial == 0)
771                 return -ENOENT;
772
773         *serial = BUS_MESSAGE_SERIAL(m);
774         return 0;
775 }
776
777 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
778         if (!m)
779                 return -EINVAL;
780         if (!serial)
781                 return -EINVAL;
782         if (m->reply_serial == 0)
783                 return -ENOENT;
784
785         *serial = m->reply_serial;
786         return 0;
787 }
788
789 int sd_bus_message_get_no_reply(sd_bus_message *m) {
790         if (!m)
791                 return -EINVAL;
792
793         return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
794 }
795
796 const char *sd_bus_message_get_path(sd_bus_message *m) {
797         if (!m)
798                 return NULL;
799
800         return m->path;
801 }
802
803 const char *sd_bus_message_get_interface(sd_bus_message *m) {
804         if (!m)
805                 return NULL;
806
807         return m->interface;
808 }
809
810 const char *sd_bus_message_get_member(sd_bus_message *m) {
811         if (!m)
812                 return NULL;
813
814         return m->member;
815 }
816 const char *sd_bus_message_get_destination(sd_bus_message *m) {
817         if (!m)
818                 return NULL;
819
820         return m->destination;
821 }
822
823 const char *sd_bus_message_get_sender(sd_bus_message *m) {
824         if (!m)
825                 return NULL;
826
827         return m->sender;
828 }
829
830 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
831         if (!m)
832                 return NULL;
833
834         if (!sd_bus_error_is_set(&m->error))
835                 return NULL;
836
837         return &m->error;
838 }
839
840 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
841         if (!m)
842                 return -EINVAL;
843         if (!uid)
844                 return -EINVAL;
845         if (!m->uid_valid)
846                 return -ESRCH;
847
848         *uid = m->uid;
849         return 0;
850 }
851
852 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
853         if (!m)
854                 return -EINVAL;
855         if (!gid)
856                 return -EINVAL;
857         if (!m->gid_valid)
858                 return -ESRCH;
859
860         *gid = m->gid;
861         return 0;
862 }
863
864 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
865         if (!m)
866                 return -EINVAL;
867         if (!pid)
868                 return -EINVAL;
869         if (m->pid <= 0)
870                 return -ESRCH;
871
872         *pid = m->pid;
873         return 0;
874 }
875
876 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
877         if (!m)
878                 return -EINVAL;
879         if (!tid)
880                 return -EINVAL;
881         if (m->tid <= 0)
882                 return -ESRCH;
883
884         *tid = m->tid;
885         return 0;
886 }
887
888 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
889         if (!m)
890                 return -EINVAL;
891         if (!usec)
892                 return -EINVAL;
893         if (m->pid_starttime <= 0)
894                 return -ESRCH;
895
896         *usec = m->pid_starttime;
897         return 0;
898 }
899
900 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
901         if (!m)
902                 return -EINVAL;
903         if (!m->label)
904                 return -ESRCH;
905
906         *ret = m->label;
907         return 0;
908 }
909
910 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
911         if (!m)
912                 return -EINVAL;
913         if (!usec)
914                 return -EINVAL;
915         if (m->monotonic <= 0)
916                 return -ESRCH;
917
918         *usec = m->monotonic;
919         return 0;
920 }
921
922 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
923         if (!m)
924                 return -EINVAL;
925         if (!usec)
926                 return -EINVAL;
927         if (m->realtime <= 0)
928                 return -ESRCH;
929
930         *usec = m->realtime;
931         return 0;
932 }
933
934 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
935         if (!m)
936                 return -EINVAL;
937         if (!ret)
938                 return -EINVAL;
939         if (!m->comm)
940                 return -ESRCH;
941
942         *ret = m->comm;
943         return 0;
944 }
945
946 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
947         if (!m)
948                 return -EINVAL;
949         if (!ret)
950                 return -EINVAL;
951         if (!m->tid_comm)
952                 return -ESRCH;
953
954         *ret = m->tid_comm;
955         return 0;
956 }
957
958 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
959         if (!m)
960                 return -EINVAL;
961         if (!ret)
962                 return -EINVAL;
963         if (!m->exe)
964                 return -ESRCH;
965
966         *ret = m->exe;
967         return 0;
968 }
969
970 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
971         if (!m)
972                 return -EINVAL;
973         if (!ret)
974                 return -EINVAL;
975         if (!m->cgroup)
976                 return -ESRCH;
977
978         *ret = m->cgroup;
979         return 0;
980 }
981
982 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
983         int r;
984
985         if (!m)
986                 return -EINVAL;
987         if (!ret)
988                 return -EINVAL;
989         if (!m->cgroup)
990                 return -ESRCH;
991
992         if (!m->unit) {
993                 r = cg_path_get_unit(m->cgroup, &m->unit);
994                 if (r < 0)
995                         return r;
996         }
997
998         *ret = m->unit;
999         return 0;
1000 }
1001
1002 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
1003         int r;
1004
1005         if (!m)
1006                 return -EINVAL;
1007         if (!ret)
1008                 return -EINVAL;
1009         if (!m->cgroup)
1010                 return -ESRCH;
1011
1012         if (!m->user_unit) {
1013                 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
1014                 if (r < 0)
1015                         return r;
1016         }
1017
1018         *ret = m->user_unit;
1019         return 0;
1020 }
1021
1022 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
1023         int r;
1024
1025         if (!m)
1026                 return -EINVAL;
1027         if (!ret)
1028                 return -EINVAL;
1029         if (!m->cgroup)
1030                 return -ESRCH;
1031
1032         if (!m->session) {
1033                 r = cg_path_get_session(m->cgroup, &m->session);
1034                 if (r < 0)
1035                         return r;
1036         }
1037
1038         *ret = m->session;
1039         return 0;
1040 }
1041
1042 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
1043         if (!m)
1044                 return -EINVAL;
1045         if (!uid)
1046                 return -EINVAL;
1047         if (!m->cgroup)
1048                 return -ESRCH;
1049
1050         return cg_path_get_owner_uid(m->cgroup, uid);
1051 }
1052
1053 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
1054         size_t n, i;
1055         const char *p;
1056         bool first;
1057
1058         if (!m)
1059                 return -EINVAL;
1060
1061         if (!m->cmdline)
1062                 return -ENOENT;
1063
1064         for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1065                 if (*p == 0)
1066                         n++;
1067
1068         m->cmdline_array = new(char*, n + 1);
1069         if (!m->cmdline_array)
1070                 return -ENOMEM;
1071
1072         for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1073                 if (first)
1074                         m->cmdline_array[i++] = (char*) p;
1075
1076                 first = *p == 0;
1077         }
1078
1079         m->cmdline_array[i] = NULL;
1080         *cmdline = m->cmdline_array;
1081
1082         return 0;
1083 }
1084
1085 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1086         if (!m)
1087                 return -EINVAL;
1088         if (!sessionid)
1089                 return -EINVAL;
1090         if (!m->audit)
1091                 return -ESRCH;
1092
1093         *sessionid = m->audit->sessionid;
1094         return 0;
1095 }
1096
1097 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1098         if (!m)
1099                 return -EINVAL;
1100         if (!uid)
1101                 return -EINVAL;
1102         if (!m->audit)
1103                 return -ESRCH;
1104
1105         *uid = m->audit->loginuid;
1106         return 0;
1107 }
1108
1109 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1110         unsigned sz;
1111
1112         if (!m)
1113                 return -EINVAL;
1114         if (capability < 0)
1115                 return -EINVAL;
1116         if (!m->capability)
1117                 return -ESRCH;
1118
1119         sz = m->capability_size / 4;
1120         if ((unsigned) capability >= sz*8)
1121                 return 0;
1122
1123         return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1124 }
1125
1126 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1127         if (!m)
1128                 return -EINVAL;
1129
1130         if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1131                 return 0;
1132
1133         if (interface && (!m->interface || !streq(m->interface, interface)))
1134                 return 0;
1135
1136         if (member &&  (!m->member || !streq(m->member, member)))
1137                 return 0;
1138
1139         return 1;
1140 }
1141
1142 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1143         if (!m)
1144                 return -EINVAL;
1145
1146         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1147                 return 0;
1148
1149         if (interface && (!m->interface || !streq(m->interface, interface)))
1150                 return 0;
1151
1152         if (member &&  (!m->member || !streq(m->member, member)))
1153                 return 0;
1154
1155         return 1;
1156 }
1157
1158 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1159         if (!m)
1160                 return -EINVAL;
1161
1162         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1163                 return 0;
1164
1165         if (name && (!m->error.name || !streq(m->error.name, name)))
1166                 return 0;
1167
1168         return 1;
1169 }
1170
1171 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1172         if (!m)
1173                 return -EINVAL;
1174         if (m->sealed)
1175                 return -EPERM;
1176         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1177                 return -EPERM;
1178
1179         if (b)
1180                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1181         else
1182                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1183
1184         return 0;
1185 }
1186
1187 static struct bus_container *message_get_container(sd_bus_message *m) {
1188         assert(m);
1189
1190         if (m->n_containers == 0)
1191                 return &m->root_container;
1192
1193         assert(m->containers);
1194         return m->containers + m->n_containers - 1;
1195 }
1196
1197 struct bus_body_part *message_append_part(sd_bus_message *m) {
1198         struct bus_body_part *part;
1199
1200         assert(m);
1201
1202         if (m->poisoned)
1203                 return NULL;
1204
1205         if (m->n_body_parts <= 0) {
1206                 part = &m->body;
1207                 zero(*part);
1208         } else {
1209                 assert(m->body_end);
1210
1211                 part = new0(struct bus_body_part, 1);
1212                 if (!part) {
1213                         m->poisoned = true;
1214                         return NULL;
1215                 }
1216
1217                 m->body_end->next = part;
1218         }
1219
1220         part->memfd = -1;
1221         m->body_end = part;
1222         m->n_body_parts ++;
1223
1224         return part;
1225 }
1226
1227 static void part_zero(struct bus_body_part *part, size_t sz) {
1228         assert(part);
1229         assert(sz > 0);
1230         assert(sz < 8);
1231
1232         /* All other fields can be left in their defaults */
1233         assert(!part->data);
1234         assert(part->memfd < 0);
1235
1236         part->size = sz;
1237         part->is_zero = true;
1238         part->sealed = true;
1239 }
1240
1241 static int part_make_space(
1242                 struct sd_bus_message *m,
1243                 struct bus_body_part *part,
1244                 size_t sz,
1245                 void **q) {
1246
1247         void *n;
1248         int r;
1249
1250         assert(m);
1251         assert(part);
1252         assert(!part->sealed);
1253
1254         if (m->poisoned)
1255                 return -ENOMEM;
1256
1257         if (!part->data && part->memfd < 0)
1258                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1259
1260         if (part->memfd >= 0) {
1261                 uint64_t u = sz;
1262
1263                 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1264                 if (r < 0) {
1265                         m->poisoned = true;
1266                         return -errno;
1267                 }
1268
1269                 if (!part->data || sz > part->mapped) {
1270                         size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1271
1272                         if (part->mapped <= 0)
1273                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1274                         else
1275                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1276
1277                         if (n == MAP_FAILED) {
1278                                 m->poisoned = true;
1279                                 return -errno;
1280                         }
1281
1282                         part->mapped = psz;
1283                         part->data = n;
1284                 }
1285
1286                 part->munmap_this = true;
1287         } else {
1288                 n = realloc(part->data, sz);
1289                 if (!n) {
1290                         m->poisoned = true;
1291                         return -ENOMEM;
1292                 }
1293
1294                 part->data = n;
1295                 part->free_this = true;
1296         }
1297
1298         if (q)
1299                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1300
1301         part->size = sz;
1302         return 0;
1303 }
1304
1305 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1306         struct bus_container *c;
1307
1308         assert(m);
1309
1310         if (expand <= 0)
1311                 return;
1312
1313         /* Update counters */
1314         for (c = m->containers; c < m->containers + m->n_containers; c++)
1315                 if (c->array_size)
1316                         *c->array_size += expand;
1317 }
1318
1319 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1320         struct bus_body_part *part = NULL;
1321         size_t start_body, end_body, padding, start_part, end_part, added;
1322         bool add_new_part;
1323         void *p;
1324         int r;
1325
1326         assert(m);
1327         assert(align > 0);
1328         assert(!m->sealed);
1329
1330         if (m->poisoned)
1331                 return NULL;
1332
1333         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1334         end_body = start_body + sz;
1335
1336         padding = start_body - m->header->body_size;
1337         added = padding + sz;
1338
1339         /* Check for 32bit overflows */
1340         if (end_body > (size_t) ((uint32_t) -1)) {
1341                 m->poisoned = true;
1342                 return NULL;
1343         }
1344
1345         add_new_part =
1346                 m->n_body_parts <= 0 ||
1347                 m->body_end->sealed ||
1348                 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1349
1350         if (add_new_part) {
1351                 if (padding > 0) {
1352                         part = message_append_part(m);
1353                         if (!part)
1354                                 return NULL;
1355
1356                         part_zero(part, padding);
1357                 }
1358
1359                 part = message_append_part(m);
1360                 if (!part)
1361                         return NULL;
1362
1363                 r = part_make_space(m, part, sz, &p);
1364                 if (r < 0)
1365                         return NULL;
1366         } else {
1367                 struct bus_container *c;
1368                 void *op;
1369                 size_t os;
1370
1371                 part = m->body_end;
1372                 op = part->data;
1373                 os = part->size;
1374
1375                 start_part = ALIGN_TO(part->size, align);
1376                 end_part = start_part + sz;
1377
1378                 r = part_make_space(m, part, end_part, &p);
1379                 if (r < 0)
1380                         return NULL;
1381
1382                 if (padding > 0) {
1383                         memset(p, 0, padding);
1384                         p = (uint8_t*) p + padding;
1385                 }
1386
1387                 /* Readjust pointers */
1388                 for (c = m->containers; c < m->containers + m->n_containers; c++)
1389                         c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1390
1391                 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1392         }
1393
1394         m->header->body_size = end_body;
1395         message_extend_containers(m, added);
1396
1397         return p;
1398 }
1399
1400 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1401         struct bus_container *c;
1402         ssize_t align, sz;
1403         uint32_t k;
1404         void *a;
1405         int fd = -1;
1406         uint32_t fdi = 0;
1407         int r;
1408
1409         if (!m)
1410                 return -EINVAL;
1411         if (!p)
1412                 return -EINVAL;
1413         if (m->sealed)
1414                 return -EPERM;
1415         if (!bus_type_is_basic(type))
1416                 return -EINVAL;
1417         if (m->poisoned)
1418                 return -ESTALE;
1419
1420         c = message_get_container(m);
1421
1422         if (c->signature && c->signature[c->index]) {
1423                 /* Container signature is already set */
1424
1425                 if (c->signature[c->index] != type)
1426                         return -ENXIO;
1427         } else {
1428                 char *e;
1429
1430                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1431                 if (c->enclosing != 0)
1432                         return -ENXIO;
1433
1434                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1435                 if (!e) {
1436                         m->poisoned = true;
1437                         return -ENOMEM;
1438                 }
1439         }
1440
1441         switch (type) {
1442
1443         case SD_BUS_TYPE_STRING:
1444         case SD_BUS_TYPE_OBJECT_PATH:
1445
1446                 align = 4;
1447                 sz = 4 + strlen(p) + 1;
1448                 break;
1449
1450         case SD_BUS_TYPE_SIGNATURE:
1451
1452                 align = 1;
1453                 sz = 1 + strlen(p) + 1;
1454                 break;
1455
1456         case SD_BUS_TYPE_BOOLEAN:
1457                 align = sz = 4;
1458
1459                 assert_cc(sizeof(int) == sizeof(uint32_t));
1460                 memcpy(&k, p, 4);
1461                 k = !!k;
1462                 p = &k;
1463                 break;
1464
1465         case SD_BUS_TYPE_UNIX_FD: {
1466                 int z, *f;
1467
1468                 if (!m->allow_fds) {
1469                         r = -ENOTSUP;
1470                         goto fail;
1471                 }
1472
1473                 align = sz = 4;
1474
1475                 z = *(int*) p;
1476                 if (z < 0) {
1477                         r = -EINVAL;
1478                         goto fail;
1479                 }
1480
1481                 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1482                 if (fd < 0) {
1483                         r = -errno;
1484                         goto fail;
1485                 }
1486
1487                 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1488                 if (!f) {
1489                         m->poisoned = true;
1490                         r = -ENOMEM;
1491                         goto fail;
1492                 }
1493
1494                 fdi = m->n_fds;
1495                 f[fdi] = fd;
1496                 m->fds = f;
1497                 m->free_fds = true;
1498                 break;
1499         }
1500
1501         default:
1502                 align = bus_type_get_alignment(type);
1503                 sz = bus_type_get_size(type);
1504                 break;
1505         }
1506
1507         assert(align > 0);
1508         assert(sz > 0);
1509
1510         a = message_extend_body(m, align, sz);
1511         if (!a) {
1512                 r = -ENOMEM;
1513                 goto fail;
1514         }
1515
1516         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1517                 *(uint32_t*) a = sz - 5;
1518                 memcpy((uint8_t*) a + 4, p, sz - 4);
1519
1520                 if (stored)
1521                         *stored = (const uint8_t*) a + 4;
1522
1523         } else if (type == SD_BUS_TYPE_SIGNATURE) {
1524                 *(uint8_t*) a = sz - 1;
1525                 memcpy((uint8_t*) a + 1, p, sz - 1);
1526
1527                 if (stored)
1528                         *stored = (const uint8_t*) a + 1;
1529         } else if (type == SD_BUS_TYPE_UNIX_FD) {
1530                 *(uint32_t*) a = fdi;
1531
1532                 if (stored)
1533                         *stored = a;
1534
1535                 m->n_fds ++;
1536
1537         } else {
1538                 memcpy(a, p, sz);
1539
1540                 if (stored)
1541                         *stored = a;
1542         }
1543
1544         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1545                 c->index++;
1546
1547         return 0;
1548
1549 fail:
1550         if (fd >= 0)
1551                 close_nointr_nofail(fd);
1552
1553         return r;
1554 }
1555
1556 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1557         return message_append_basic(m, type, p, NULL);
1558 }
1559
1560 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1561         struct bus_container *c;
1562         void *a;
1563
1564         if (!m)
1565                 return -EINVAL;
1566         if (!s)
1567                 return -EINVAL;
1568         if (m->sealed)
1569                 return -EPERM;
1570         if (m->poisoned)
1571                 return -ESTALE;
1572
1573         c = message_get_container(m);
1574
1575         if (c->signature && c->signature[c->index]) {
1576                 /* Container signature is already set */
1577
1578                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1579                         return -ENXIO;
1580         } else {
1581                 char *e;
1582
1583                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1584                 if (c->enclosing != 0)
1585                         return -ENXIO;
1586
1587                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1588                 if (!e) {
1589                         m->poisoned = true;
1590                         return -ENOMEM;
1591                 }
1592         }
1593
1594         a = message_extend_body(m, 4, 4 + size + 1);
1595         if (!a)
1596                 return -ENOMEM;
1597
1598         *(uint32_t*) a = size;
1599         *s = (char*) a + 4;
1600
1601         (*s)[size] = 0;
1602
1603         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1604                 c->index++;
1605
1606         return 0;
1607 }
1608
1609 static int bus_message_open_array(
1610                 sd_bus_message *m,
1611                 struct bus_container *c,
1612                 const char *contents,
1613                 uint32_t **array_size) {
1614
1615         unsigned nindex;
1616         void *a, *op;
1617         int alignment;
1618         size_t os;
1619         struct bus_body_part *o;
1620
1621         assert(m);
1622         assert(c);
1623         assert(contents);
1624         assert(array_size);
1625
1626         if (!signature_is_single(contents, true))
1627                 return -EINVAL;
1628
1629         alignment = bus_type_get_alignment(contents[0]);
1630         if (alignment < 0)
1631                 return alignment;
1632
1633         if (c->signature && c->signature[c->index]) {
1634
1635                 /* Verify the existing signature */
1636
1637                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1638                         return -ENXIO;
1639
1640                 if (!startswith(c->signature + c->index + 1, contents))
1641                         return -ENXIO;
1642
1643                 nindex = c->index + 1 + strlen(contents);
1644         } else {
1645                 char *e;
1646
1647                 if (c->enclosing != 0)
1648                         return -ENXIO;
1649
1650                 /* Extend the existing signature */
1651
1652                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1653                 if (!e) {
1654                         m->poisoned = true;
1655                         return -ENOMEM;
1656                 }
1657
1658                 nindex = e - c->signature;
1659         }
1660
1661         a = message_extend_body(m, 4, 4);
1662         if (!a)
1663                 return -ENOMEM;
1664
1665         o = m->body_end;
1666         op = m->body_end->data;
1667         os = m->body_end->size;
1668
1669         /* Add alignment between size and first element */
1670         if (!message_extend_body(m, alignment, 0))
1671                 return -ENOMEM;
1672
1673         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1674                 c->index = nindex;
1675
1676         /* location of array size might have changed so let's readjust a */
1677         if (o == m->body_end)
1678                 a = adjust_pointer(a, op, os, m->body_end->data);
1679
1680         *(uint32_t*) a = 0;
1681         *array_size = a;
1682         return 0;
1683 }
1684
1685 static int bus_message_open_variant(
1686                 sd_bus_message *m,
1687                 struct bus_container *c,
1688                 const char *contents) {
1689
1690         size_t l;
1691         void *a;
1692
1693         assert(m);
1694         assert(c);
1695         assert(contents);
1696
1697         if (!signature_is_single(contents, false))
1698                 return -EINVAL;
1699
1700         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1701                 return -EINVAL;
1702
1703         if (c->signature && c->signature[c->index]) {
1704
1705                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1706                         return -ENXIO;
1707
1708         } else {
1709                 char *e;
1710
1711                 if (c->enclosing != 0)
1712                         return -ENXIO;
1713
1714                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1715                 if (!e) {
1716                         m->poisoned = true;
1717                         return -ENOMEM;
1718                 }
1719         }
1720
1721         l = strlen(contents);
1722         a = message_extend_body(m, 1, 1 + l + 1);
1723         if (!a)
1724                 return -ENOMEM;
1725
1726         *(uint8_t*) a = l;
1727         memcpy((uint8_t*) a + 1, contents, l + 1);
1728
1729         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1730                 c->index++;
1731
1732         return 0;
1733 }
1734
1735 static int bus_message_open_struct(
1736                 sd_bus_message *m,
1737                 struct bus_container *c,
1738                 const char *contents) {
1739
1740         size_t nindex;
1741
1742         assert(m);
1743         assert(c);
1744         assert(contents);
1745
1746         if (!signature_is_valid(contents, false))
1747                 return -EINVAL;
1748
1749         if (c->signature && c->signature[c->index]) {
1750                 size_t l;
1751
1752                 l = strlen(contents);
1753
1754                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1755                     !startswith(c->signature + c->index + 1, contents) ||
1756                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1757                         return -ENXIO;
1758
1759                 nindex = c->index + 1 + l + 1;
1760         } else {
1761                 char *e;
1762
1763                 if (c->enclosing != 0)
1764                         return -ENXIO;
1765
1766                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1767                 if (!e) {
1768                         m->poisoned = true;
1769                         return -ENOMEM;
1770                 }
1771
1772                 nindex = e - c->signature;
1773         }
1774
1775         /* Align contents to 8 byte boundary */
1776         if (!message_extend_body(m, 8, 0))
1777                 return -ENOMEM;
1778
1779         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1780                 c->index = nindex;
1781
1782         return 0;
1783 }
1784
1785 static int bus_message_open_dict_entry(
1786                 sd_bus_message *m,
1787                 struct bus_container *c,
1788                 const char *contents) {
1789
1790         size_t nindex;
1791
1792         assert(m);
1793         assert(c);
1794         assert(contents);
1795
1796         if (!signature_is_pair(contents))
1797                 return -EINVAL;
1798
1799         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1800                 return -ENXIO;
1801
1802         if (c->signature && c->signature[c->index]) {
1803                 size_t l;
1804
1805                 l = strlen(contents);
1806
1807                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1808                     !startswith(c->signature + c->index + 1, contents) ||
1809                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1810                         return -ENXIO;
1811
1812                 nindex = c->index + 1 + l + 1;
1813         } else
1814                 return -ENXIO;
1815
1816         /* Align contents to 8 byte boundary */
1817         if (!message_extend_body(m, 8, 0))
1818                 return -ENOMEM;
1819
1820         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1821                 c->index = nindex;
1822
1823         return 0;
1824 }
1825
1826 int sd_bus_message_open_container(
1827                 sd_bus_message *m,
1828                 char type,
1829                 const char *contents) {
1830
1831         struct bus_container *c, *w;
1832         uint32_t *array_size = NULL;
1833         char *signature;
1834         size_t before;
1835         int r;
1836
1837         if (!m)
1838                 return -EINVAL;
1839         if (m->sealed)
1840                 return -EPERM;
1841         if (!contents)
1842                 return -EINVAL;
1843         if (m->poisoned)
1844                 return -ESTALE;
1845
1846         /* Make sure we have space for one more container */
1847         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1848         if (!w) {
1849                 m->poisoned = true;
1850                 return -ENOMEM;
1851         }
1852
1853         m->containers = w;
1854
1855         c = message_get_container(m);
1856
1857         signature = strdup(contents);
1858         if (!signature) {
1859                 m->poisoned = true;
1860                 return -ENOMEM;
1861         }
1862
1863         /* Save old index in the parent container, in case we have to
1864          * abort this container */
1865         c->saved_index = c->index;
1866         before = m->header->body_size;
1867
1868         if (type == SD_BUS_TYPE_ARRAY)
1869                 r = bus_message_open_array(m, c, contents, &array_size);
1870         else if (type == SD_BUS_TYPE_VARIANT)
1871                 r = bus_message_open_variant(m, c, contents);
1872         else if (type == SD_BUS_TYPE_STRUCT)
1873                 r = bus_message_open_struct(m, c, contents);
1874         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1875                 r = bus_message_open_dict_entry(m, c, contents);
1876         else
1877                 r = -EINVAL;
1878
1879         if (r < 0) {
1880                 free(signature);
1881                 return r;
1882         }
1883
1884         /* OK, let's fill it in */
1885         w += m->n_containers++;
1886         w->enclosing = type;
1887         w->signature = signature;
1888         w->index = 0;
1889         w->array_size = array_size;
1890         w->before = before;
1891         w->begin = m->rindex;
1892
1893         return 0;
1894 }
1895
1896 int sd_bus_message_close_container(sd_bus_message *m) {
1897         struct bus_container *c;
1898
1899         if (!m)
1900                 return -EINVAL;
1901         if (m->sealed)
1902                 return -EPERM;
1903         if (m->n_containers <= 0)
1904                 return -EINVAL;
1905         if (m->poisoned)
1906                 return -ESTALE;
1907
1908         c = message_get_container(m);
1909         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1910                 if (c->signature && c->signature[c->index] != 0)
1911                         return -EINVAL;
1912
1913         free(c->signature);
1914         m->n_containers--;
1915
1916         return 0;
1917 }
1918
1919 typedef struct {
1920         const char *types;
1921         unsigned n_struct;
1922         unsigned n_array;
1923 } TypeStack;
1924
1925 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1926         assert(stack);
1927         assert(max > 0);
1928
1929         if (*i >= max)
1930                 return -EINVAL;
1931
1932         stack[*i].types = types;
1933         stack[*i].n_struct = n_struct;
1934         stack[*i].n_array = n_array;
1935         (*i)++;
1936
1937         return 0;
1938 }
1939
1940 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1941         assert(stack);
1942         assert(max > 0);
1943         assert(types);
1944         assert(n_struct);
1945         assert(n_array);
1946
1947         if (*i <= 0)
1948                 return 0;
1949
1950         (*i)--;
1951         *types = stack[*i].types;
1952         *n_struct = stack[*i].n_struct;
1953         *n_array = stack[*i].n_array;
1954
1955         return 1;
1956 }
1957
1958 int bus_message_append_ap(
1959                 sd_bus_message *m,
1960                 const char *types,
1961                 va_list ap) {
1962
1963         unsigned n_array, n_struct;
1964         TypeStack stack[BUS_CONTAINER_DEPTH];
1965         unsigned stack_ptr = 0;
1966         int r;
1967
1968         assert(m);
1969
1970         if (!types)
1971                 return 0;
1972
1973         n_array = (unsigned) -1;
1974         n_struct = strlen(types);
1975
1976         for (;;) {
1977                 const char *t;
1978
1979                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1980                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1981                         if (r < 0)
1982                                 return r;
1983                         if (r == 0)
1984                                 break;
1985
1986                         r = sd_bus_message_close_container(m);
1987                         if (r < 0)
1988                                 return r;
1989
1990                         continue;
1991                 }
1992
1993                 t = types;
1994                 if (n_array != (unsigned) -1)
1995                         n_array --;
1996                 else {
1997                         types ++;
1998                         n_struct--;
1999                 }
2000
2001                 switch (*t) {
2002
2003                 case SD_BUS_TYPE_BYTE: {
2004                         uint8_t x;
2005
2006                         x = (uint8_t) va_arg(ap, int);
2007                         r = sd_bus_message_append_basic(m, *t, &x);
2008                         break;
2009                 }
2010
2011                 case SD_BUS_TYPE_BOOLEAN:
2012                 case SD_BUS_TYPE_INT32:
2013                 case SD_BUS_TYPE_UINT32:
2014                 case SD_BUS_TYPE_UNIX_FD: {
2015                         uint32_t x;
2016
2017                         /* We assume a boolean is the same as int32_t */
2018                         assert_cc(sizeof(int32_t) == sizeof(int));
2019
2020                         x = va_arg(ap, uint32_t);
2021                         r = sd_bus_message_append_basic(m, *t, &x);
2022                         break;
2023                 }
2024
2025                 case SD_BUS_TYPE_INT16:
2026                 case SD_BUS_TYPE_UINT16: {
2027                         uint16_t x;
2028
2029                         x = (uint16_t) va_arg(ap, int);
2030                         r = sd_bus_message_append_basic(m, *t, &x);
2031                         break;
2032                 }
2033
2034                 case SD_BUS_TYPE_INT64:
2035                 case SD_BUS_TYPE_UINT64:
2036                 case SD_BUS_TYPE_DOUBLE: {
2037                         uint64_t x;
2038
2039                         x = va_arg(ap, uint64_t);
2040                         r = sd_bus_message_append_basic(m, *t, &x);
2041                         break;
2042                 }
2043
2044                 case SD_BUS_TYPE_STRING:
2045                 case SD_BUS_TYPE_OBJECT_PATH:
2046                 case SD_BUS_TYPE_SIGNATURE: {
2047                         const char *x;
2048
2049                         x = va_arg(ap, const char*);
2050                         r = sd_bus_message_append_basic(m, *t, x);
2051                         break;
2052                 }
2053
2054                 case SD_BUS_TYPE_ARRAY: {
2055                         size_t k;
2056
2057                         r = signature_element_length(t + 1, &k);
2058                         if (r < 0)
2059                                 return r;
2060
2061                         {
2062                                 char s[k + 1];
2063                                 memcpy(s, t + 1, k);
2064                                 s[k] = 0;
2065
2066                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2067                                 if (r < 0)
2068                                         return r;
2069                         }
2070
2071                         if (n_array == (unsigned) -1) {
2072                                 types += k;
2073                                 n_struct -= k;
2074                         }
2075
2076                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2077                         if (r < 0)
2078                                 return r;
2079
2080                         types = t + 1;
2081                         n_struct = k;
2082                         n_array = va_arg(ap, unsigned);
2083
2084                         break;
2085                 }
2086
2087                 case SD_BUS_TYPE_VARIANT: {
2088                         const char *s;
2089
2090                         s = va_arg(ap, const char*);
2091                         if (!s)
2092                                 return -EINVAL;
2093
2094                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2095                         if (r < 0)
2096                                 return r;
2097
2098                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2099                         if (r < 0)
2100                                 return r;
2101
2102                         types = s;
2103                         n_struct = strlen(s);
2104                         n_array = (unsigned) -1;
2105
2106                         break;
2107                 }
2108
2109                 case SD_BUS_TYPE_STRUCT_BEGIN:
2110                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2111                         size_t k;
2112
2113                         r = signature_element_length(t, &k);
2114                         if (r < 0)
2115                                 return r;
2116
2117                         {
2118                                 char s[k - 1];
2119
2120                                 memcpy(s, t + 1, k - 2);
2121                                 s[k - 2] = 0;
2122
2123                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2124                                 if (r < 0)
2125                                         return r;
2126                         }
2127
2128                         if (n_array == (unsigned) -1) {
2129                                 types += k - 1;
2130                                 n_struct -= k - 1;
2131                         }
2132
2133                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2134                         if (r < 0)
2135                                 return r;
2136
2137                         types = t + 1;
2138                         n_struct = k - 2;
2139                         n_array = (unsigned) -1;
2140
2141                         break;
2142                 }
2143
2144                 default:
2145                         r = -EINVAL;
2146                 }
2147
2148                 if (r < 0)
2149                         return r;
2150         }
2151
2152         return 0;
2153 }
2154
2155 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2156         va_list ap;
2157         int r;
2158
2159         if (!m)
2160                 return -EINVAL;
2161         if (m->sealed)
2162                 return -EPERM;
2163         if (m->poisoned)
2164                 return -ESTALE;
2165         if (!types)
2166                 return 0;
2167
2168         va_start(ap, types);
2169         r = bus_message_append_ap(m, types, ap);
2170         va_end(ap);
2171
2172         return r;
2173 }
2174
2175 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2176         ssize_t align, sz;
2177         void *a;
2178         int r;
2179
2180         if (!m)
2181                 return -EINVAL;
2182         if (m->sealed)
2183                 return -EPERM;
2184         if (!bus_type_is_trivial(type))
2185                 return -EINVAL;
2186         if (!ptr && size > 0)
2187                 return -EINVAL;
2188         if (m->poisoned)
2189                 return -ESTALE;
2190
2191         align = bus_type_get_alignment(type);
2192         sz = bus_type_get_size(type);
2193
2194         assert_se(align > 0);
2195         assert_se(sz > 0);
2196
2197         if (size % sz != 0)
2198                 return -EINVAL;
2199
2200         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2201         if (r < 0)
2202                 return r;
2203
2204         a = message_extend_body(m, align, size);
2205         if (!a)
2206                 return -ENOMEM;
2207
2208         r = sd_bus_message_close_container(m);
2209         if (r < 0)
2210                 return r;
2211
2212         *ptr = a;
2213         return 0;
2214 }
2215
2216 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2217         int r;
2218         void *p;
2219
2220         if (!ptr && size > 0)
2221                 return -EINVAL;
2222
2223         r = sd_bus_message_append_array_space(m, type, size, &p);
2224         if (r < 0)
2225                 return r;
2226
2227         if (size > 0)
2228                 memcpy(p, ptr, size);
2229
2230         return 0;
2231 }
2232
2233 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2234         _cleanup_close_ int copy_fd = -1;
2235         struct bus_body_part *part;
2236         ssize_t align, sz;
2237         uint64_t size;
2238         void *a;
2239         int r;
2240
2241         if (!m)
2242                 return -EINVAL;
2243         if (!memfd)
2244                 return -EINVAL;
2245         if (m->sealed)
2246                 return -EPERM;
2247         if (!bus_type_is_trivial(type))
2248                 return -EINVAL;
2249         if (m->poisoned)
2250                 return -ESTALE;
2251
2252         r = sd_memfd_set_sealed(memfd, true);
2253         if (r < 0)
2254                 return r;
2255
2256         copy_fd = sd_memfd_dup_fd(memfd);
2257         if (copy_fd < 0)
2258                 return copy_fd;
2259
2260         r = sd_memfd_get_size(memfd, &size);
2261         if (r < 0)
2262                 return r;
2263
2264         align = bus_type_get_alignment(type);
2265         sz = bus_type_get_size(type);
2266
2267         assert_se(align > 0);
2268         assert_se(sz > 0);
2269
2270         if (size % sz != 0)
2271                 return -EINVAL;
2272
2273         if (size > (uint64_t) (uint32_t) -1)
2274                 return -EINVAL;
2275
2276         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2277         if (r < 0)
2278                 return r;
2279
2280         a = message_extend_body(m, align, 0);
2281         if (!a)
2282                 return -ENOMEM;
2283
2284         part = message_append_part(m);
2285         if (!part)
2286                 return -ENOMEM;
2287
2288         part->memfd = copy_fd;
2289         part->sealed = true;
2290         part->size = size;
2291         copy_fd = -1;
2292
2293         message_extend_containers(m, size);
2294         m->header->body_size += size;
2295
2296         return sd_bus_message_close_container(m);
2297 }
2298
2299 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2300         _cleanup_close_ int copy_fd = -1;
2301         struct bus_body_part *part;
2302         struct bus_container *c;
2303         uint64_t size;
2304         void *a;
2305         int r;
2306
2307         if (!m)
2308                 return -EINVAL;
2309         if (!memfd)
2310                 return -EINVAL;
2311         if (m->sealed)
2312                 return -EPERM;
2313         if (m->poisoned)
2314                 return -ESTALE;
2315
2316         r = sd_memfd_set_sealed(memfd, true);
2317         if (r < 0)
2318                 return r;
2319
2320         copy_fd = sd_memfd_dup_fd(memfd);
2321         if (copy_fd < 0)
2322                 return copy_fd;
2323
2324         r = sd_memfd_get_size(memfd, &size);
2325         if (r < 0)
2326                 return r;
2327
2328         /* We require this to be NUL terminated */
2329         if (size == 0)
2330                 return -EINVAL;
2331
2332         if (size > (uint64_t) (uint32_t) -1)
2333                 return -EINVAL;
2334
2335         c = message_get_container(m);
2336         if (c->signature && c->signature[c->index]) {
2337                 /* Container signature is already set */
2338
2339                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2340                         return -ENXIO;
2341         } else {
2342                 char *e;
2343
2344                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2345                 if (c->enclosing != 0)
2346                         return -ENXIO;
2347
2348                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2349                 if (!e) {
2350                         m->poisoned = true;
2351                         return -ENOMEM;
2352                 }
2353         }
2354
2355         a = message_extend_body(m, 4, 4);
2356         if (!a)
2357                 return -ENOMEM;
2358
2359         *(uint32_t*) a = size - 1;
2360
2361         part = message_append_part(m);
2362         if (!part)
2363                 return -ENOMEM;
2364
2365         part->memfd = copy_fd;
2366         part->sealed = true;
2367         part->size = size;
2368         copy_fd = -1;
2369
2370         message_extend_containers(m, size);
2371         m->header->body_size += size;
2372
2373         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2374                 c->index++;
2375
2376         return 0;
2377 }
2378
2379 int bus_body_part_map(struct bus_body_part *part) {
2380         void *p;
2381         size_t psz;
2382
2383         assert_se(part);
2384
2385         if (part->data)
2386                 return 0;
2387
2388         if (part->size <= 0)
2389                 return 0;
2390
2391         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2392         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2393                 static const uint8_t zeroes[7] = { };
2394                 part->data = (void*) zeroes;
2395                 return 0;
2396         }
2397
2398         psz = PAGE_ALIGN(part->size);
2399
2400         if (part->memfd >= 0)
2401                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2402         else if (part->is_zero)
2403                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2404         else
2405                 return -EINVAL;
2406
2407         if (p == MAP_FAILED)
2408                 return -errno;
2409
2410         part->mapped = psz;
2411         part->data = p;
2412         part->munmap_this = true;
2413
2414         return 0;
2415 }
2416
2417 void bus_body_part_unmap(struct bus_body_part *part) {
2418
2419         assert_se(part);
2420
2421         if (part->memfd < 0)
2422                 return;
2423
2424         if (!part->data)
2425                 return;
2426
2427         if (!part->munmap_this)
2428                 return;
2429
2430         assert_se(munmap(part->data, part->mapped) == 0);
2431
2432         part->data = NULL;
2433         part->mapped = 0;
2434         part->munmap_this = false;
2435
2436         return;
2437 }
2438
2439 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2440         size_t k, start, end;
2441
2442         assert(rindex);
2443         assert(align > 0);
2444
2445         start = ALIGN_TO((size_t) *rindex, align);
2446         end = start + nbytes;
2447
2448         if (end > sz)
2449                 return -EBADMSG;
2450
2451         /* Verify that padding is 0 */
2452         for (k = *rindex; k < start; k++)
2453                 if (((const uint8_t*) p)[k] != 0)
2454                         return -EBADMSG;
2455
2456         if (r)
2457                 *r = (uint8_t*) p + start;
2458
2459         *rindex = end;
2460
2461         return 1;
2462 }
2463
2464 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2465         struct bus_container *c;
2466
2467         assert(m);
2468
2469         c = message_get_container(m);
2470         if (!c->array_size)
2471                 return false;
2472
2473         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2474 }
2475
2476 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2477         struct bus_body_part *part;
2478         size_t begin;
2479         int r;
2480
2481         assert(m);
2482
2483         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2484                 part = m->cached_rindex_part;
2485                 begin = m->cached_rindex_part_begin;
2486         } else {
2487                 part = &m->body;
2488                 begin = 0;
2489         }
2490
2491         while (part) {
2492                 if (index < begin)
2493                         return NULL;
2494
2495                 if (index + sz <= begin + part->size) {
2496
2497                         r = bus_body_part_map(part);
2498                         if (r < 0)
2499                                 return NULL;
2500
2501                         if (p)
2502                                 *p = (uint8_t*) part->data + index - begin;
2503
2504                         m->cached_rindex_part = part;
2505                         m->cached_rindex_part_begin = begin;
2506
2507                         return part;
2508                 }
2509
2510                 begin += part->size;
2511                 part = part->next;
2512         }
2513
2514         return NULL;
2515 }
2516
2517 static int message_peek_body(
2518                 sd_bus_message *m,
2519                 size_t *rindex,
2520                 size_t align,
2521                 size_t nbytes,
2522                 void **ret) {
2523
2524         size_t k, start, end, padding;
2525         struct bus_body_part *part;
2526         uint8_t *q;
2527
2528         assert(m);
2529         assert(rindex);
2530         assert(align > 0);
2531
2532         if (message_end_of_array(m, *rindex))
2533                 return 0;
2534
2535         start = ALIGN_TO((size_t) *rindex, align);
2536         padding = start - *rindex;
2537         end = start + nbytes;
2538
2539         if (end > BUS_MESSAGE_BODY_SIZE(m))
2540                 return -EBADMSG;
2541
2542         part = find_part(m, *rindex, padding, (void**) &q);
2543         if (!part)
2544                 return -EBADMSG;
2545
2546         if (q) {
2547                 /* Verify padding */
2548                 for (k = 0; k < padding; k++)
2549                         if (q[k] != 0)
2550                                 return -EBADMSG;
2551         }
2552
2553         part = find_part(m, start, nbytes, (void**) &q);
2554         if (!part || !q)
2555                 return -EBADMSG;
2556
2557         *rindex = end;
2558
2559         if (ret)
2560                 *ret = q;
2561
2562         return 1;
2563 }
2564
2565 static bool validate_nul(const char *s, size_t l) {
2566
2567         /* Check for NUL chars in the string */
2568         if (memchr(s, 0, l))
2569                 return false;
2570
2571         /* Check for NUL termination */
2572         if (s[l] != 0)
2573                 return false;
2574
2575         return true;
2576 }
2577
2578 static bool validate_string(const char *s, size_t l) {
2579
2580         if (!validate_nul(s, l))
2581                 return false;
2582
2583         /* Check if valid UTF8 */
2584         if (!utf8_is_valid(s))
2585                 return false;
2586
2587         return true;
2588 }
2589
2590 static bool validate_signature(const char *s, size_t l) {
2591
2592         if (!validate_nul(s, l))
2593                 return false;
2594
2595         /* Check if valid signature */
2596         if (!signature_is_valid(s, true))
2597                 return false;
2598
2599         return true;
2600 }
2601
2602 static bool validate_object_path(const char *s, size_t l) {
2603
2604         if (!validate_nul(s, l))
2605                 return false;
2606
2607         if (!object_path_is_valid(s))
2608                 return false;
2609
2610         return true;
2611 }
2612
2613 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2614         struct bus_container *c;
2615         int r;
2616         void *q;
2617
2618         if (!m)
2619                 return -EINVAL;
2620         if (!m->sealed)
2621                 return -EPERM;
2622         if (!bus_type_is_basic(type))
2623                 return -EINVAL;
2624         if (!p)
2625                 return -EINVAL;
2626
2627         c = message_get_container(m);
2628
2629         if (!c->signature || c->signature[c->index] == 0)
2630                 return 0;
2631
2632         if (c->signature[c->index] != type)
2633                 return -ENXIO;
2634
2635         switch (type) {
2636
2637         case SD_BUS_TYPE_STRING:
2638         case SD_BUS_TYPE_OBJECT_PATH: {
2639                 uint32_t l;
2640                 size_t rindex;
2641
2642                 rindex = m->rindex;
2643                 r = message_peek_body(m, &rindex, 4, 4, &q);
2644                 if (r <= 0)
2645                         return r;
2646
2647                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2648                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2649                 if (r < 0)
2650                         return r;
2651                 if (r == 0)
2652                         return -EBADMSG;
2653
2654                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2655                         if (!validate_object_path(q, l))
2656                                 return -EBADMSG;
2657                 } else {
2658                         if (!validate_string(q, l))
2659                                 return -EBADMSG;
2660                 }
2661
2662                 m->rindex = rindex;
2663                 *(const char**) p = q;
2664                 break;
2665         }
2666
2667         case SD_BUS_TYPE_SIGNATURE: {
2668                 uint8_t l;
2669                 size_t rindex;
2670
2671                 rindex = m->rindex;
2672                 r = message_peek_body(m, &rindex, 1, 1, &q);
2673                 if (r <= 0)
2674                         return r;
2675
2676                 l = *(uint8_t*) q;
2677                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2678                 if (r < 0)
2679                         return r;
2680                 if (r == 0)
2681                         return -EBADMSG;
2682
2683                 if (!validate_signature(q, l))
2684                         return -EBADMSG;
2685
2686                 m->rindex = rindex;
2687                 *(const char**) p = q;
2688                 break;
2689         }
2690
2691         default: {
2692                 ssize_t sz, align;
2693                 size_t rindex;
2694
2695                 align = bus_type_get_alignment(type);
2696                 sz = bus_type_get_size(type);
2697                 assert(align > 0 && sz > 0);
2698
2699                 rindex = m->rindex;
2700                 r = message_peek_body(m, &rindex, align, sz, &q);
2701                 if (r <= 0)
2702                         return r;
2703
2704                 switch (type) {
2705
2706                 case SD_BUS_TYPE_BYTE:
2707                         *(uint8_t*) p = *(uint8_t*) q;
2708                         break;
2709
2710                 case SD_BUS_TYPE_BOOLEAN:
2711                         *(int*) p = !!*(uint32_t*) q;
2712                         break;
2713
2714                 case SD_BUS_TYPE_INT16:
2715                 case SD_BUS_TYPE_UINT16:
2716                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2717                         break;
2718
2719                 case SD_BUS_TYPE_INT32:
2720                 case SD_BUS_TYPE_UINT32:
2721                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2722                         break;
2723
2724                 case SD_BUS_TYPE_INT64:
2725                 case SD_BUS_TYPE_UINT64:
2726                 case SD_BUS_TYPE_DOUBLE:
2727                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2728                         break;
2729
2730                 case SD_BUS_TYPE_UNIX_FD: {
2731                         uint32_t j;
2732
2733                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2734                         if (j >= m->n_fds)
2735                                 return -EBADMSG;
2736
2737                         *(int*) p = m->fds[j];
2738                         break;
2739                 }
2740
2741                 default:
2742                         assert_not_reached("Unknown basic type...");
2743                 }
2744
2745                 m->rindex = rindex;
2746
2747                 break;
2748         }
2749         }
2750
2751         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2752                 c->index++;
2753
2754         return 1;
2755 }
2756
2757 static int bus_message_enter_array(
2758                 sd_bus_message *m,
2759                 struct bus_container *c,
2760                 const char *contents,
2761                 uint32_t **array_size) {
2762
2763         size_t rindex;
2764         void *q;
2765         int r, alignment;
2766
2767         assert(m);
2768         assert(c);
2769         assert(contents);
2770         assert(array_size);
2771
2772         if (!signature_is_single(contents, true))
2773                 return -EINVAL;
2774
2775         alignment = bus_type_get_alignment(contents[0]);
2776         if (alignment < 0)
2777                 return alignment;
2778
2779         if (!c->signature || c->signature[c->index] == 0)
2780                 return 0;
2781
2782         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2783                 return -ENXIO;
2784
2785         if (!startswith(c->signature + c->index + 1, contents))
2786                 return -ENXIO;
2787
2788         rindex = m->rindex;
2789         r = message_peek_body(m, &rindex, 4, 4, &q);
2790         if (r <= 0)
2791                 return r;
2792
2793         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2794                 return -EBADMSG;
2795
2796         r = message_peek_body(m, &rindex, alignment, 0, NULL);
2797         if (r < 0)
2798                 return r;
2799         if (r == 0)
2800                 return -EBADMSG;
2801
2802         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2803                 c->index += 1 + strlen(contents);
2804
2805         m->rindex = rindex;
2806
2807         *array_size = (uint32_t*) q;
2808
2809         return 1;
2810 }
2811
2812 static int bus_message_enter_variant(
2813                 sd_bus_message *m,
2814                 struct bus_container *c,
2815                 const char *contents) {
2816
2817         size_t rindex;
2818         uint8_t l;
2819         void *q;
2820         int r;
2821
2822         assert(m);
2823         assert(c);
2824         assert(contents);
2825
2826         if (!signature_is_single(contents, false))
2827                 return -EINVAL;
2828
2829         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2830                 return -EINVAL;
2831
2832         if (!c->signature || c->signature[c->index] == 0)
2833                 return 0;
2834
2835         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2836                 return -ENXIO;
2837
2838         rindex = m->rindex;
2839         r = message_peek_body(m, &rindex, 1, 1, &q);
2840         if (r <= 0)
2841                 return r;
2842
2843         l = *(uint8_t*) q;
2844         r = message_peek_body(m, &rindex, 1, l+1, &q);
2845         if (r < 0)
2846                 return r;
2847         if (r == 0)
2848                 return -EBADMSG;
2849
2850         if (!validate_signature(q, l))
2851                 return -EBADMSG;
2852
2853         if (!streq(q, contents))
2854                 return -ENXIO;
2855
2856         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2857                 c->index++;
2858
2859         m->rindex = rindex;
2860
2861         return 1;
2862 }
2863
2864 static int bus_message_enter_struct(
2865                 sd_bus_message *m,
2866                 struct bus_container *c,
2867                 const char *contents) {
2868
2869         size_t l;
2870         int r;
2871
2872         assert(m);
2873         assert(c);
2874         assert(contents);
2875
2876         if (!signature_is_valid(contents, false))
2877                 return -EINVAL;
2878
2879         if (!c->signature || c->signature[c->index] == 0)
2880                 return 0;
2881
2882         l = strlen(contents);
2883
2884         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2885             !startswith(c->signature + c->index + 1, contents) ||
2886             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2887                 return -ENXIO;
2888
2889         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2890         if (r <= 0)
2891                 return r;
2892
2893         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2894                 c->index += 1 + l + 1;
2895
2896         return 1;
2897 }
2898
2899 static int bus_message_enter_dict_entry(
2900                 sd_bus_message *m,
2901                 struct bus_container *c,
2902                 const char *contents) {
2903
2904         size_t l;
2905         int r;
2906
2907         assert(m);
2908         assert(c);
2909         assert(contents);
2910
2911         if (!signature_is_pair(contents))
2912                 return -EINVAL;
2913
2914         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2915                 return -ENXIO;
2916
2917         if (!c->signature || c->signature[c->index] == 0)
2918                 return 0;
2919
2920         l = strlen(contents);
2921
2922         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2923             !startswith(c->signature + c->index + 1, contents) ||
2924             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2925                 return -ENXIO;
2926
2927         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2928         if (r <= 0)
2929                 return r;
2930
2931         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2932                 c->index += 1 + l + 1;
2933
2934         return 1;
2935 }
2936
2937 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2938         struct bus_container *c, *w;
2939         uint32_t *array_size = NULL;
2940         char *signature;
2941         size_t before;
2942         int r;
2943
2944         if (!m)
2945                 return -EINVAL;
2946         if (!m->sealed)
2947                 return -EPERM;
2948         if (!contents)
2949                 return -EINVAL;
2950
2951         /*
2952          * We enforce a global limit on container depth, that is much
2953          * higher than the 32 structs and 32 arrays the specification
2954          * mandates. This is simpler to implement for us, and we need
2955          * this only to ensure our container array doesn't grow
2956          * without bounds. We are happy to return any data from a
2957          * message as long as the data itself is valid, even if the
2958          * overall message might be not.
2959          *
2960          * Note that the message signature is validated when
2961          * parsing the headers, and that validation does check the
2962          * 32/32 limit.
2963          *
2964          * Note that the specification defines no limits on the depth
2965          * of stacked variants, but we do.
2966          */
2967         if (m->n_containers >= BUS_CONTAINER_DEPTH)
2968                 return -EBADMSG;
2969
2970         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2971         if (!w)
2972                 return -ENOMEM;
2973         m->containers = w;
2974
2975         c = message_get_container(m);
2976
2977         if (!c->signature || c->signature[c->index] == 0)
2978                 return 0;
2979
2980         signature = strdup(contents);
2981         if (!signature)
2982                 return -ENOMEM;
2983
2984         c->saved_index = c->index;
2985         before = m->rindex;
2986
2987         if (type == SD_BUS_TYPE_ARRAY)
2988                 r = bus_message_enter_array(m, c, contents, &array_size);
2989         else if (type == SD_BUS_TYPE_VARIANT)
2990                 r = bus_message_enter_variant(m, c, contents);
2991         else if (type == SD_BUS_TYPE_STRUCT)
2992                 r = bus_message_enter_struct(m, c, contents);
2993         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2994                 r = bus_message_enter_dict_entry(m, c, contents);
2995         else
2996                 r = -EINVAL;
2997
2998         if (r <= 0) {
2999                 free(signature);
3000                 return r;
3001         }
3002
3003         /* OK, let's fill it in */
3004         w += m->n_containers++;
3005         w->enclosing = type;
3006         w->signature = signature;
3007         w->index = 0;
3008         w->array_size = array_size;
3009         w->before = before;
3010         w->begin = m->rindex;
3011
3012         return 1;
3013 }
3014
3015 int sd_bus_message_exit_container(sd_bus_message *m) {
3016         struct bus_container *c;
3017
3018         if (!m)
3019                 return -EINVAL;
3020         if (!m->sealed)
3021                 return -EPERM;
3022         if (m->n_containers <= 0)
3023                 return -EINVAL;
3024
3025         c = message_get_container(m);
3026         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3027                 uint32_t l;
3028
3029                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3030                 if (c->begin + l != m->rindex)
3031                         return -EBUSY;
3032
3033         } else {
3034                 if (c->signature && c->signature[c->index] != 0)
3035                         return -EINVAL;
3036         }
3037
3038         free(c->signature);
3039         m->n_containers--;
3040
3041         return 1;
3042 }
3043
3044 static void message_quit_container(sd_bus_message *m) {
3045         struct bus_container *c;
3046
3047         assert(m);
3048         assert(m->sealed);
3049         assert(m->n_containers > 0);
3050
3051         c = message_get_container(m);
3052
3053         /* Undo seeks */
3054         assert(m->rindex >= c->before);
3055         m->rindex = c->before;
3056
3057         /* Free container */
3058         free(c->signature);
3059         m->n_containers--;
3060
3061         /* Correct index of new top-level container */
3062         c = message_get_container(m);
3063         c->index = c->saved_index;
3064 }
3065
3066 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3067         struct bus_container *c;
3068         int r;
3069
3070         if (!m)
3071                 return -EINVAL;
3072         if (!m->sealed)
3073                 return -EPERM;
3074
3075         c = message_get_container(m);
3076
3077         if (!c->signature || c->signature[c->index] == 0)
3078                 goto eof;
3079
3080         if (message_end_of_array(m, m->rindex))
3081                 goto eof;
3082
3083         if (bus_type_is_basic(c->signature[c->index])) {
3084                 if (contents)
3085                         *contents = NULL;
3086                 if (type)
3087                         *type = c->signature[c->index];
3088                 return 1;
3089         }
3090
3091         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3092
3093                 if (contents) {
3094                         size_t l;
3095                         char *sig;
3096
3097                         r = signature_element_length(c->signature+c->index+1, &l);
3098                         if (r < 0)
3099                                 return r;
3100
3101                         assert(l >= 1);
3102
3103                         sig = strndup(c->signature + c->index + 1, l);
3104                         if (!sig)
3105                                 return -ENOMEM;
3106
3107                         free(m->peeked_signature);
3108                         m->peeked_signature = sig;
3109
3110                         *contents = sig;
3111                 }
3112
3113                 if (type)
3114                         *type = SD_BUS_TYPE_ARRAY;
3115
3116                 return 1;
3117         }
3118
3119         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3120             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3121
3122                 if (contents) {
3123                         size_t l;
3124                         char *sig;
3125
3126                         r = signature_element_length(c->signature+c->index, &l);
3127                         if (r < 0)
3128                                 return r;
3129
3130                         assert(l >= 2);
3131                         sig = strndup(c->signature + c->index + 1, l - 2);
3132                         if (!sig)
3133                                 return -ENOMEM;
3134
3135                         free(m->peeked_signature);
3136                         m->peeked_signature = sig;
3137
3138                         *contents = sig;
3139                 }
3140
3141                 if (type)
3142                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3143
3144                 return 1;
3145         }
3146
3147         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3148                 if (contents) {
3149                         size_t rindex, l;
3150                         void *q;
3151
3152                         rindex = m->rindex;
3153                         r = message_peek_body(m, &rindex, 1, 1, &q);
3154                         if (r < 0)
3155                                 return r;
3156                         if (r == 0)
3157                                 goto eof;
3158
3159                         l = *(uint8_t*) q;
3160                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3161                         if (r < 0)
3162                                 return r;
3163                         if (r == 0)
3164                                 return -EBADMSG;
3165
3166                         if (!validate_signature(q, l))
3167                                 return -EBADMSG;
3168
3169                         *contents = q;
3170                 }
3171
3172                 if (type)
3173                         *type = SD_BUS_TYPE_VARIANT;
3174
3175                 return 1;
3176         }
3177
3178         return -EINVAL;
3179
3180 eof:
3181         if (type)
3182                 *type = c->enclosing;
3183         if (contents)
3184                 *contents = NULL;
3185         return 0;
3186 }
3187
3188 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3189         struct bus_container *c;
3190
3191         if (!m)
3192                 return -EINVAL;
3193         if (!m->sealed)
3194                 return -EPERM;
3195
3196         if (complete) {
3197                 message_reset_containers(m);
3198                 m->rindex = 0;
3199                 m->root_container.index = 0;
3200
3201                 c = message_get_container(m);
3202         } else {
3203                 c = message_get_container(m);
3204
3205                 c->index = 0;
3206                 m->rindex = c->begin;
3207         }
3208
3209         return !isempty(c->signature);
3210 }
3211 static int message_read_ap(
3212                 sd_bus_message *m,
3213                 const char *types,
3214                 va_list ap) {
3215
3216         unsigned n_array, n_struct;
3217         TypeStack stack[BUS_CONTAINER_DEPTH];
3218         unsigned stack_ptr = 0;
3219         int r;
3220
3221         assert(m);
3222
3223         if (!types)
3224                 return 0;
3225
3226         /* Ideally, we'd just call ourselves recursively on every
3227          * complex type. However, the state of a va_list that is
3228          * passed to a function is undefined after that function
3229          * returns. This means we need to docode the va_list linearly
3230          * in a single stackframe. We hence implement our own
3231          * home-grown stack in an array. */
3232
3233         n_array = (unsigned) -1;
3234         n_struct = strlen(types);
3235
3236         for (;;) {
3237                 const char *t;
3238
3239                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3240                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3241                         if (r < 0)
3242                                 return r;
3243                         if (r == 0)
3244                                 break;
3245
3246                         r = sd_bus_message_exit_container(m);
3247                         if (r < 0)
3248                                 return r;
3249
3250                         continue;
3251                 }
3252
3253                 t = types;
3254                 if (n_array != (unsigned) -1)
3255                         n_array --;
3256                 else {
3257                         types ++;
3258                         n_struct--;
3259                 }
3260
3261                 switch (*t) {
3262
3263                 case SD_BUS_TYPE_BYTE:
3264                 case SD_BUS_TYPE_BOOLEAN:
3265                 case SD_BUS_TYPE_INT16:
3266                 case SD_BUS_TYPE_UINT16:
3267                 case SD_BUS_TYPE_INT32:
3268                 case SD_BUS_TYPE_UINT32:
3269                 case SD_BUS_TYPE_INT64:
3270                 case SD_BUS_TYPE_UINT64:
3271                 case SD_BUS_TYPE_DOUBLE:
3272                 case SD_BUS_TYPE_STRING:
3273                 case SD_BUS_TYPE_OBJECT_PATH:
3274                 case SD_BUS_TYPE_SIGNATURE:
3275                 case SD_BUS_TYPE_UNIX_FD: {
3276                         void *p;
3277
3278                         p = va_arg(ap, void*);
3279                         r = sd_bus_message_read_basic(m, *t, p);
3280                         if (r < 0)
3281                                 return r;
3282                         if (r == 0)
3283                                 return -ENXIO;
3284
3285                         break;
3286                 }
3287
3288                 case SD_BUS_TYPE_ARRAY: {
3289                         size_t k;
3290
3291                         r = signature_element_length(t + 1, &k);
3292                         if (r < 0)
3293                                 return r;
3294
3295                         {
3296                                 char s[k + 1];
3297                                 memcpy(s, t + 1, k);
3298                                 s[k] = 0;
3299
3300                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3301                                 if (r < 0)
3302                                         return r;
3303                                 if (r == 0)
3304                                         return -ENXIO;
3305                         }
3306
3307                         if (n_array == (unsigned) -1) {
3308                                 types += k;
3309                                 n_struct -= k;
3310                         }
3311
3312                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3313                         if (r < 0)
3314                                 return r;
3315
3316                         types = t + 1;
3317                         n_struct = k;
3318                         n_array = va_arg(ap, unsigned);
3319
3320                         break;
3321                 }
3322
3323                 case SD_BUS_TYPE_VARIANT: {
3324                         const char *s;
3325
3326                         s = va_arg(ap, const char *);
3327                         if (!s)
3328                                 return -EINVAL;
3329
3330                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3331                         if (r < 0)
3332                                 return r;
3333                         if (r == 0)
3334                                 return -ENXIO;
3335
3336                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3337                         if (r < 0)
3338                                 return r;
3339
3340                         types = s;
3341                         n_struct = strlen(s);
3342                         n_array = (unsigned) -1;
3343
3344                         break;
3345                 }
3346
3347                 case SD_BUS_TYPE_STRUCT_BEGIN:
3348                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3349                         size_t k;
3350
3351                         r = signature_element_length(t, &k);
3352                         if (r < 0)
3353                                 return r;
3354
3355                         {
3356                                 char s[k - 1];
3357                                 memcpy(s, t + 1, k - 2);
3358                                 s[k - 2] = 0;
3359
3360                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3361                                 if (r < 0)
3362                                         return r;
3363                                 if (r == 0)
3364                                         return -ENXIO;
3365                         }
3366
3367                         if (n_array == (unsigned) -1) {
3368                                 types += k - 1;
3369                                 n_struct -= k - 1;
3370                         }
3371
3372                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3373                         if (r < 0)
3374                                 return r;
3375
3376                         types = t + 1;
3377                         n_struct = k - 2;
3378                         n_array = (unsigned) -1;
3379
3380                         break;
3381                 }
3382
3383                 default:
3384                         return -EINVAL;
3385                 }
3386         }
3387
3388         return 1;
3389 }
3390
3391 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3392         va_list ap;
3393         int r;
3394
3395         if (!m)
3396                 return -EINVAL;
3397         if (!m->sealed)
3398                 return -EPERM;
3399         if (!types)
3400                 return -EINVAL;
3401
3402         va_start(ap, types);
3403         r = message_read_ap(m, types, ap);
3404         va_end(ap);
3405
3406         return r;
3407 }
3408
3409 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3410         struct bus_container *c;
3411         void *p;
3412         size_t sz;
3413         ssize_t align;
3414         int r;
3415
3416         if (!m)
3417                 return -EINVAL;
3418         if (!m->sealed)
3419                 return -EPERM;
3420         if (!bus_type_is_trivial(type))
3421                 return -EINVAL;
3422         if (!ptr)
3423                 return -EINVAL;
3424         if (!size)
3425                 return -EINVAL;
3426         if (BUS_MESSAGE_NEED_BSWAP(m))
3427                 return -ENOTSUP;
3428
3429         align = bus_type_get_alignment(type);
3430         if (align < 0)
3431                 return align;
3432
3433         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3434         if (r <= 0)
3435                 return r;
3436
3437         c = message_get_container(m);
3438         sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3439
3440         r = message_peek_body(m, &m->rindex, align, sz, &p);
3441         if (r < 0)
3442                 goto fail;
3443         if (r == 0) {
3444                 r = -EBADMSG;
3445                 goto fail;
3446         }
3447
3448         r = sd_bus_message_exit_container(m);
3449         if (r < 0)
3450                 goto fail;
3451
3452         *ptr = (const void*) p;
3453         *size = sz;
3454
3455         return 1;
3456
3457 fail:
3458         message_quit_container(m);
3459         return r;
3460 }
3461
3462 static int message_peek_fields(
3463                 sd_bus_message *m,
3464                 size_t *rindex,
3465                 size_t align,
3466                 size_t nbytes,
3467                 void **ret) {
3468
3469         assert(m);
3470         assert(rindex);
3471         assert(align > 0);
3472
3473         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3474 }
3475
3476 static int message_peek_field_uint32(
3477                 sd_bus_message *m,
3478                 size_t *ri,
3479                 uint32_t *ret) {
3480
3481         int r;
3482         void *q;
3483
3484         assert(m);
3485         assert(ri);
3486
3487         r = message_peek_fields(m, ri, 4, 4, &q);
3488         if (r < 0)
3489                 return r;
3490
3491         if (ret)
3492                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3493
3494         return 0;
3495 }
3496
3497 static int message_peek_field_string(
3498                 sd_bus_message *m,
3499                 bool (*validate)(const char *p),
3500                 size_t *ri,
3501                 const char **ret) {
3502
3503         uint32_t l;
3504         int r;
3505         void *q;
3506
3507         assert(m);
3508         assert(ri);
3509
3510         r = message_peek_field_uint32(m, ri, &l);
3511         if (r < 0)
3512                 return r;
3513
3514         r = message_peek_fields(m, ri, 1, l+1, &q);
3515         if (r < 0)
3516                 return r;
3517
3518         if (validate) {
3519                 if (!validate_nul(q, l))
3520                         return -EBADMSG;
3521
3522                 if (!validate(q))
3523                         return -EBADMSG;
3524         } else {
3525                 if (!validate_string(q, l))
3526                         return -EBADMSG;
3527         }
3528
3529         if (ret)
3530                 *ret = q;
3531
3532         return 0;
3533 }
3534
3535 static int message_peek_field_signature(
3536                 sd_bus_message *m,
3537                 size_t *ri,
3538                 const char **ret) {
3539
3540         size_t l;
3541         int r;
3542         void *q;
3543
3544         assert(m);
3545         assert(ri);
3546
3547         r = message_peek_fields(m, ri, 1, 1, &q);
3548         if (r < 0)
3549                 return r;
3550
3551         l = *(uint8_t*) q;
3552         r = message_peek_fields(m, ri, 1, l+1, &q);
3553         if (r < 0)
3554                 return r;
3555
3556         if (!validate_signature(q, l))
3557                 return -EBADMSG;
3558
3559         if (ret)
3560                 *ret = q;
3561
3562         return 0;
3563 }
3564
3565 static int message_skip_fields(
3566                 sd_bus_message *m,
3567                 size_t *ri,
3568                 uint32_t array_size,
3569                 const char **signature) {
3570
3571         size_t original_index;
3572         int r;
3573
3574         assert(m);
3575         assert(ri);
3576         assert(signature);
3577
3578         original_index = *ri;
3579
3580         for (;;) {
3581                 char t;
3582                 size_t l;
3583
3584                 if (array_size != (uint32_t) -1 &&
3585                     array_size <= *ri - original_index)
3586                         return 0;
3587
3588                 t = **signature;
3589                 if (!t)
3590                         return 0;
3591
3592                 if (t == SD_BUS_TYPE_STRING) {
3593
3594                         r = message_peek_field_string(m, NULL, ri, NULL);
3595                         if (r < 0)
3596                                 return r;
3597
3598                         (*signature)++;
3599
3600                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3601
3602                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3603                         if (r < 0)
3604                                 return r;
3605
3606                         (*signature)++;
3607
3608                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3609
3610                         r = message_peek_field_signature(m, ri, NULL);
3611                         if (r < 0)
3612                                 return r;
3613
3614                         (*signature)++;
3615
3616                 } else if (bus_type_is_basic(t)) {
3617                         ssize_t align, k;
3618
3619                         align = bus_type_get_alignment(t);
3620                         k = bus_type_get_size(t);
3621                         assert(align > 0 && k > 0);
3622
3623                         r = message_peek_fields(m, ri, align, k, NULL);
3624                         if (r < 0)
3625                                 return r;
3626
3627                         (*signature)++;
3628
3629                 } else if (t == SD_BUS_TYPE_ARRAY) {
3630
3631                         r = signature_element_length(*signature+1, &l);
3632                         if (r < 0)
3633                                 return r;
3634
3635                         assert(l >= 1);
3636                         {
3637                                 char sig[l-1], *s;
3638                                 uint32_t nas;
3639                                 int alignment;
3640
3641                                 strncpy(sig, *signature + 1, l-1);
3642                                 s = sig;
3643
3644                                 alignment = bus_type_get_alignment(sig[0]);
3645                                 if (alignment < 0)
3646                                         return alignment;
3647
3648                                 r = message_peek_field_uint32(m, ri, &nas);
3649                                 if (r < 0)
3650                                         return r;
3651                                 if (nas > BUS_ARRAY_MAX_SIZE)
3652                                         return -EBADMSG;
3653
3654                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
3655                                 if (r < 0)
3656                                         return r;
3657
3658                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
3659                                 if (r < 0)
3660                                         return r;
3661                         }
3662
3663                         (*signature) += 1 + l;
3664
3665                 } else if (t == SD_BUS_TYPE_VARIANT) {
3666                         const char *s;
3667
3668                         r = message_peek_field_signature(m, ri, &s);
3669                         if (r < 0)
3670                                 return r;
3671
3672                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3673                         if (r < 0)
3674                                 return r;
3675
3676                         (*signature)++;
3677
3678                 } else if (t == SD_BUS_TYPE_STRUCT ||
3679                            t == SD_BUS_TYPE_DICT_ENTRY) {
3680
3681                         r = signature_element_length(*signature, &l);
3682                         if (r < 0)
3683                                 return r;
3684
3685                         assert(l >= 2);
3686                         {
3687                                 char sig[l-1], *s;
3688                                 strncpy(sig, *signature + 1, l-1);
3689                                 s = sig;
3690
3691                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3692                                 if (r < 0)
3693                                         return r;
3694                         }
3695
3696                         *signature += l;
3697                 } else
3698                         return -EINVAL;
3699         }
3700 }
3701
3702 int bus_message_parse_fields(sd_bus_message *m) {
3703         size_t ri;
3704         int r;
3705         uint32_t unix_fds = 0;
3706
3707         assert(m);
3708
3709         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3710                 const char *signature;
3711                 uint8_t *header;
3712
3713                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3714                 if (r < 0)
3715                         return r;
3716
3717                 r = message_peek_field_signature(m, &ri, &signature);
3718                 if (r < 0)
3719                         return r;
3720
3721                 switch (*header) {
3722                 case _SD_BUS_MESSAGE_HEADER_INVALID:
3723                         return -EBADMSG;
3724
3725                 case SD_BUS_MESSAGE_HEADER_PATH:
3726
3727                         if (m->path)
3728                                 return -EBADMSG;
3729
3730                         if (!streq(signature, "o"))
3731                                 return -EBADMSG;
3732
3733                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3734                         break;
3735
3736                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3737
3738                         if (m->interface)
3739                                 return -EBADMSG;
3740
3741                         if (!streq(signature, "s"))
3742                                 return -EBADMSG;
3743
3744                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3745                         break;
3746
3747                 case SD_BUS_MESSAGE_HEADER_MEMBER:
3748
3749                         if (m->member)
3750                                 return -EBADMSG;
3751
3752                         if (!streq(signature, "s"))
3753                                 return -EBADMSG;
3754
3755                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3756                         break;
3757
3758                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3759
3760                         if (m->error.name)
3761                                 return -EBADMSG;
3762
3763                         if (!streq(signature, "s"))
3764                                 return -EBADMSG;
3765
3766                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3767                         break;
3768
3769                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3770
3771                         if (m->destination)
3772                                 return -EBADMSG;
3773
3774                         if (!streq(signature, "s"))
3775                                 return -EBADMSG;
3776
3777                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3778                         break;
3779
3780                 case SD_BUS_MESSAGE_HEADER_SENDER:
3781
3782                         if (m->sender)
3783                                 return -EBADMSG;
3784
3785                         if (!streq(signature, "s"))
3786                                 return -EBADMSG;
3787
3788                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3789                         break;
3790
3791
3792                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3793                         const char *s;
3794                         char *c;
3795
3796                         if (m->root_container.signature)
3797                                 return -EBADMSG;
3798
3799                         if (!streq(signature, "g"))
3800                                 return -EBADMSG;
3801
3802                         r = message_peek_field_signature(m, &ri, &s);
3803                         if (r < 0)
3804                                 return r;
3805
3806                         c = strdup(s);
3807                         if (!c)
3808                                 return -ENOMEM;
3809
3810                         free(m->root_container.signature);
3811                         m->root_container.signature = c;
3812                         break;
3813                 }
3814
3815                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3816                         if (m->reply_serial != 0)
3817                                 return -EBADMSG;
3818
3819                         if (!streq(signature, "u"))
3820                                 return -EBADMSG;
3821
3822                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3823                         if (r < 0)
3824                                 return r;
3825
3826                         if (m->reply_serial == 0)
3827                                 return -EBADMSG;
3828
3829                         break;
3830
3831                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3832                         if (unix_fds != 0)
3833                                 return -EBADMSG;
3834
3835                         if (!streq(signature, "u"))
3836                                 return -EBADMSG;
3837
3838                         r = message_peek_field_uint32(m, &ri, &unix_fds);
3839                         if (r < 0)
3840                                 return -EBADMSG;
3841
3842                         if (unix_fds == 0)
3843                                 return -EBADMSG;
3844
3845                         break;
3846
3847                 default:
3848                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3849                 }
3850
3851                 if (r < 0)
3852                         return r;
3853         }
3854
3855         if (m->n_fds != unix_fds)
3856                 return -EBADMSG;
3857
3858         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3859                 return -EBADMSG;
3860
3861         switch (m->header->type) {
3862
3863         case SD_BUS_MESSAGE_TYPE_SIGNAL:
3864                 if (!m->path || !m->interface || !m->member)
3865                         return -EBADMSG;
3866                 break;
3867
3868         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3869
3870                 if (!m->path || !m->member)
3871                         return -EBADMSG;
3872
3873                 break;
3874
3875         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3876
3877                 if (m->reply_serial == 0)
3878                         return -EBADMSG;
3879                 break;
3880
3881         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3882
3883                 if (m->reply_serial == 0 || !m->error.name)
3884                         return -EBADMSG;
3885                 break;
3886         }
3887
3888         /* Try to read the error message, but if we can't it's a non-issue */
3889         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3890                 sd_bus_message_read(m, "s", &m->error.message);
3891
3892         return 0;
3893 }
3894
3895 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3896         struct bus_body_part *part;
3897         size_t l, a;
3898         unsigned i;
3899         int r;
3900
3901         assert(m);
3902
3903         if (m->sealed)
3904                 return -EPERM;
3905
3906         if (m->n_containers > 0)
3907                 return -EBADMSG;
3908
3909         if (m->poisoned)
3910                 return -ESTALE;
3911
3912         /* If there's a non-trivial signature set, then add it in here */
3913         if (!isempty(m->root_container.signature)) {
3914                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3915                 if (r < 0)
3916                         return r;
3917         }
3918
3919         if (m->n_fds > 0) {
3920                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3921                 if (r < 0)
3922                         return r;
3923         }
3924
3925         /* Add padding at the end of the fields part, since we know
3926          * the body needs to start at an 8 byte alignment. We made
3927          * sure we allocated enough space for this, so all we need to
3928          * do here is to zero it out. */
3929         l = BUS_MESSAGE_FIELDS_SIZE(m);
3930         a = ALIGN8(l) - l;
3931         if (a > 0)
3932                 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3933
3934         /* If this is something we can send as memfd, then let's seal
3935         the memfd now. Note that we can send memfds as payload only
3936         for directed messages, and not for broadcasts. */
3937         if (m->destination && m->bus && m->bus->use_memfd) {
3938                 MESSAGE_FOREACH_PART(part, i, m)
3939                         if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3940                                 bus_body_part_unmap(part);
3941
3942                                 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3943                                         part->sealed = true;
3944                         }
3945         }
3946
3947         m->header->serial = serial;
3948         m->sealed = true;
3949
3950         return 0;
3951 }
3952
3953 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3954         if (!m)
3955                 return -EINVAL;
3956         if (!destination)
3957                 return -EINVAL;
3958         if (m->sealed)
3959                 return -EPERM;
3960         if (m->destination)
3961                 return -EEXIST;
3962
3963         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3964 }
3965
3966 int bus_message_dump(sd_bus_message *m) {
3967         const char *u = NULL, *uu = NULL, *s = NULL;
3968         char **cmdline = NULL;
3969         unsigned level = 1;
3970         int r;
3971         uid_t owner, audit_loginuid;
3972         uint32_t audit_sessionid;
3973
3974         assert(m);
3975
3976         printf("Message %p\n"
3977                "\tn_ref=%u\n"
3978                "\tendian=%c\n"
3979                "\ttype=%i\n"
3980                "\tflags=%u\n"
3981                "\tversion=%u\n"
3982                "\tserial=%u\n"
3983                "\tfields_size=%u\n"
3984                "\tbody_size=%u\n"
3985                "\tpath=%s\n"
3986                "\tinterface=%s\n"
3987                "\tmember=%s\n"
3988                "\tdestination=%s\n"
3989                "\tsender=%s\n"
3990                "\tsignature=%s\n"
3991                "\treply_serial=%u\n"
3992                "\terror.name=%s\n"
3993                "\terror.message=%s\n"
3994                "\tsealed=%s\n"
3995                "\tn_body_parts=%u\n",
3996                m,
3997                m->n_ref,
3998                m->header->endian,
3999                m->header->type,
4000                m->header->flags,
4001                m->header->version,
4002                BUS_MESSAGE_SERIAL(m),
4003                BUS_MESSAGE_FIELDS_SIZE(m),
4004                BUS_MESSAGE_BODY_SIZE(m),
4005                strna(m->path),
4006                strna(m->interface),
4007                strna(m->member),
4008                strna(m->destination),
4009                strna(m->sender),
4010                strna(m->root_container.signature),
4011                m->reply_serial,
4012                strna(m->error.name),
4013                strna(m->error.message),
4014                yes_no(m->sealed),
4015                m->n_body_parts);
4016
4017         if (m->pid != 0)
4018                 printf("\tpid=%lu\n", (unsigned long) m->pid);
4019         if (m->tid != 0)
4020                 printf("\ttid=%lu\n", (unsigned long) m->tid);
4021         if (m->uid_valid)
4022                 printf("\tuid=%lu\n", (unsigned long) m->uid);
4023         if (m->gid_valid)
4024                 printf("\tgid=%lu\n", (unsigned long) m->gid);
4025         if (m->pid_starttime != 0)
4026                 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4027         if (m->monotonic != 0)
4028                 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4029         if (m->realtime != 0)
4030                 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
4031         if (m->exe)
4032                 printf("\texe=[%s]\n", m->exe);
4033         if (m->comm)
4034                 printf("\tcomm=[%s]\n", m->comm);
4035         if (m->tid_comm)
4036                 printf("\ttid_comm=[%s]\n", m->tid_comm);
4037         if (m->label)
4038                 printf("\tlabel=[%s]\n", m->label);
4039         if (m->cgroup)
4040                 printf("\tcgroup=[%s]\n", m->cgroup);
4041
4042         sd_bus_message_get_unit(m, &u);
4043         if (u)
4044                 printf("\tunit=[%s]\n", u);
4045         sd_bus_message_get_user_unit(m, &uu);
4046         if (uu)
4047                 printf("\tuser_unit=[%s]\n", uu);
4048         sd_bus_message_get_session(m, &s);
4049         if (s)
4050                 printf("\tsession=[%s]\n", s);
4051         if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4052                 printf("\towner_uid=%lu\n", (unsigned long) owner);
4053         if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4054                 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4055         if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4056                 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4057
4058         printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
4059
4060         if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4061                 char **c;
4062
4063                 fputs("\tcmdline=[", stdout);
4064                 STRV_FOREACH(c, cmdline) {
4065                         if (c != cmdline)
4066                                 putchar(' ');
4067
4068                         fputs(*c, stdout);
4069                 }
4070
4071                 fputs("]\n", stdout);
4072         }
4073
4074         r = sd_bus_message_rewind(m, true);
4075         if (r < 0) {
4076                 log_error("Failed to rewind: %s", strerror(-r));
4077                 return r;
4078         }
4079
4080         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4081
4082         for(;;) {
4083                 _cleanup_free_ char *prefix = NULL;
4084                 const char *contents = NULL;
4085                 char type;
4086                 union {
4087                         uint8_t u8;
4088                         uint16_t u16;
4089                         int16_t s16;
4090                         uint32_t u32;
4091                         int32_t s32;
4092                         uint64_t u64;
4093                         int64_t s64;
4094                         double d64;
4095                         const char *string;
4096                         int i;
4097                 } basic;
4098
4099                 r = sd_bus_message_peek_type(m, &type, &contents);
4100                 if (r < 0) {
4101                         log_error("Failed to peek type: %s", strerror(-r));
4102                         return r;
4103                 }
4104                 if (r == 0) {
4105                         if (level <= 1)
4106                                 break;
4107
4108                         r = sd_bus_message_exit_container(m);
4109                         if (r < 0) {
4110                                 log_error("Failed to exit container: %s", strerror(-r));
4111                                 return r;
4112                         }
4113
4114                         level--;
4115
4116                         prefix = strrep("\t", level);
4117                         if (!prefix)
4118                                 return log_oom();
4119
4120                         if (type == SD_BUS_TYPE_ARRAY)
4121                                 printf("%s} END_ARRAY \n", prefix);
4122                         else if (type == SD_BUS_TYPE_VARIANT)
4123                                 printf("%s} END_VARIANT\n", prefix);
4124                         else if (type == SD_BUS_TYPE_STRUCT)
4125                                 printf("%s} END_STRUCT\n", prefix);
4126                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
4127                                 printf("%s} END_DICT_ENTRY\n", prefix);
4128
4129                         continue;
4130                 }
4131
4132                 prefix = strrep("\t", level);
4133                 if (!prefix)
4134                         return log_oom();
4135
4136                 if (bus_type_is_container(type) > 0) {
4137                         r = sd_bus_message_enter_container(m, type, contents);
4138                         if (r < 0) {
4139                                 log_error("Failed to enter container: %s", strerror(-r));
4140                                 return r;
4141                         }
4142
4143                         if (type == SD_BUS_TYPE_ARRAY)
4144                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4145                         else if (type == SD_BUS_TYPE_VARIANT)
4146                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4147                         else if (type == SD_BUS_TYPE_STRUCT)
4148                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4149                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
4150                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4151
4152                         level ++;
4153
4154                         continue;
4155                 }
4156
4157                 r = sd_bus_message_read_basic(m, type, &basic);
4158                 if (r < 0) {
4159                         log_error("Failed to get basic: %s", strerror(-r));
4160                         return r;
4161                 }
4162
4163                 switch (type) {
4164
4165                 case SD_BUS_TYPE_BYTE:
4166                         printf("%sBYTE: %u\n", prefix, basic.u8);
4167                         break;
4168
4169                 case SD_BUS_TYPE_BOOLEAN:
4170                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4171                         break;
4172
4173                 case SD_BUS_TYPE_INT16:
4174                         printf("%sINT16: %i\n", prefix, basic.s16);
4175                         break;
4176
4177                 case SD_BUS_TYPE_UINT16:
4178                         printf("%sUINT16: %u\n", prefix, basic.u16);
4179                         break;
4180
4181                 case SD_BUS_TYPE_INT32:
4182                         printf("%sINT32: %i\n", prefix, basic.s32);
4183                         break;
4184
4185                 case SD_BUS_TYPE_UINT32:
4186                         printf("%sUINT32: %u\n", prefix, basic.u32);
4187                         break;
4188
4189                 case SD_BUS_TYPE_INT64:
4190                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4191                         break;
4192
4193                 case SD_BUS_TYPE_UINT64:
4194                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4195                         break;
4196
4197                 case SD_BUS_TYPE_DOUBLE:
4198                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
4199                         break;
4200
4201                 case SD_BUS_TYPE_STRING:
4202                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4203                         break;
4204
4205                 case SD_BUS_TYPE_OBJECT_PATH:
4206                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4207                         break;
4208
4209                 case SD_BUS_TYPE_SIGNATURE:
4210                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4211                         break;
4212
4213                 case SD_BUS_TYPE_UNIX_FD:
4214                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
4215                         break;
4216
4217                 default:
4218                         assert_not_reached("Unknown basic type.");
4219                 }
4220         }
4221
4222         printf("} END_MESSAGE\n");
4223         return 0;
4224 }
4225
4226 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4227         size_t total;
4228         void *p, *e;
4229         unsigned i;
4230         struct bus_body_part *part;
4231
4232         assert(m);
4233         assert(buffer);
4234         assert(sz);
4235
4236         total = BUS_MESSAGE_SIZE(m);
4237
4238         p = malloc(total);
4239         if (!p)
4240                 return -ENOMEM;
4241
4242         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4243         MESSAGE_FOREACH_PART(part, i, m)
4244                 e = mempcpy(e, part->data, part->size);
4245
4246         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4247
4248         *buffer = p;
4249         *sz = total;
4250
4251         return 0;
4252 }
4253
4254 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4255         int r;
4256
4257         assert(m);
4258         assert(l);
4259
4260         r = sd_bus_message_enter_container(m, 'a', "s");
4261         if (r < 0)
4262                 return r;
4263
4264         for (;;) {
4265                 const char *s;
4266
4267                 r = sd_bus_message_read_basic(m, 's', &s);
4268                 if (r < 0)
4269                         return r;
4270                 if (r == 0)
4271                         break;
4272
4273                 r = strv_extend(l, s);
4274                 if (r < 0)
4275                         return r;
4276         }
4277
4278         r = sd_bus_message_exit_container(m);
4279         if (r < 0)
4280                 return r;
4281
4282         return 0;
4283 }
4284
4285 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4286         int r;
4287         const char *t = NULL;
4288         unsigned j;
4289
4290         assert(m);
4291
4292         r = sd_bus_message_rewind(m, true);
4293         if (r < 0)
4294                 return NULL;
4295
4296         for (j = 0; j <= i; j++) {
4297                 char type;
4298
4299                 r = sd_bus_message_peek_type(m, &type, NULL);
4300                 if (r < 0)
4301                         return NULL;
4302
4303                 if (type != SD_BUS_TYPE_STRING &&
4304                     type != SD_BUS_TYPE_OBJECT_PATH &&
4305                     type != SD_BUS_TYPE_SIGNATURE)
4306                         return NULL;
4307
4308                 r = sd_bus_message_read_basic(m, type, &t);
4309                 if (r < 0)
4310                         return NULL;
4311         }
4312
4313         return t;
4314 }
4315
4316 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4317         size_t full;
4318
4319         assert(h);
4320         assert(size);
4321
4322         if (size < sizeof(struct bus_header))
4323                 return false;
4324
4325         full = sizeof(struct bus_header) +
4326                 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4327
4328         return size >= full;
4329 }
4330
4331 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4332         size_t fs, bs;
4333
4334         assert(h);
4335         assert(sum);
4336
4337         if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4338                 fs = h->fields_size;
4339                 bs = h->body_size;
4340         } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4341                 fs = bswap_32(h->fields_size);
4342                 bs = bswap_32(h->body_size);
4343         } else
4344                 return -EBADMSG;
4345
4346         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4347         return 0;
4348 }
4349
4350 int bus_message_to_errno(sd_bus_message *m) {
4351         assert(m);
4352
4353         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
4354                 return 0;
4355
4356         return bus_error_to_errno(&m->error);
4357 }
4358
4359 int sd_bus_message_get_signature(sd_bus_message *m, int complete, const char **signature) {
4360         struct bus_container *c;
4361
4362         if (!m)
4363                 return -EINVAL;
4364         if (!signature)
4365                 return -EINVAL;
4366
4367         c = complete ? &m->root_container : message_get_container(m);
4368         *signature = c->signature ?: "";
4369         return 0;
4370 }