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