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