chiark / gitweb /
3a748356743f99ae63c0dc0bb4b17433061673e0
[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
24 #include "util.h"
25 #include "utf8.h"
26
27 #include "sd-bus.h"
28 #include "bus-message.h"
29 #include "bus-internal.h"
30 #include "bus-type.h"
31 #include "bus-signature.h"
32
33 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
34
35 static void reset_containers(sd_bus_message *m) {
36         unsigned i;
37
38         assert(m);
39
40         for (i = 0; i < m->n_containers; i++)
41                 free(m->containers[i].signature);
42
43         free(m->containers);
44         m->containers = NULL;
45
46         m->n_containers = 0;
47         m->root_container.index = 0;
48 }
49
50 static void message_free(sd_bus_message *m) {
51         unsigned i;
52
53         assert(m);
54
55         if (m->free_header)
56                 free(m->header);
57
58         if (m->free_fields)
59                 free(m->fields);
60
61         if (m->free_body)
62                 free(m->body);
63
64         for (i = 0; i < m->n_fds; i++)
65                 close_nointr_nofail(m->fds[i]);
66
67         reset_containers(m);
68         free(m->root_container.signature);
69
70         free(m->peeked_signature);
71         free(m);
72 }
73
74 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
75         size_t start, n;
76         void *k;
77
78         assert(p);
79         assert(sz);
80         assert(align > 0);
81
82         start = ALIGN_TO((size_t) *sz, align);
83         n = start + extend;
84
85         if (n == *sz)
86                 return (uint8_t*) *p + start;
87
88         if (n > (size_t) ((uint32_t) -1))
89                 return NULL;
90
91         k = realloc(*p, n);
92         if (!k)
93                 return NULL;
94
95         /* Zero out padding */
96         if (start > *sz)
97                 memset((uint8_t*) k + *sz, 0, start - *sz);
98
99         *p = k;
100         *sz = n;
101
102         return (uint8_t*) k + start;
103 }
104
105 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
106         void *p, *o;
107
108         assert(m);
109
110         o = m->fields;
111         p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
112         if (!p)
113                 return NULL;
114
115         if (o != m->fields) {
116                 /* Adjust quick access pointers */
117
118                 if (m->path)
119                         m->path = (const char*) m->fields + (m->path - (const char*) o);
120                 if (m->interface)
121                         m->interface = (const char*) m->fields + (m->interface - (const char*) o);
122                 if (m->member)
123                         m->member = (const char*) m->fields + (m->member - (const char*) o);
124                 if (m->destination)
125                         m->destination = (const char*) m->fields + (m->destination - (const char*) o);
126                 if (m->sender)
127                         m->sender = (const char*) m->fields + (m->sender - (const char*) o);
128                 if (m->signature)
129                         m->signature = (const char*) m->fields + (m->signature - (const char*) o);
130                 if (m->error.name)
131                         m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
132         }
133
134         m->free_fields = true;
135
136         return p;
137 }
138
139 static int message_append_field_string(
140                 sd_bus_message *m,
141                 uint8_t h,
142                 char type,
143                 const char *s,
144                 const char **ret) {
145
146         size_t l;
147         uint8_t *p;
148
149         assert(m);
150
151         l = strlen(s);
152         if (l > (size_t) (uint32_t) -1)
153                 return -EINVAL;
154
155         /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
156         p = message_extend_fields(m, 8, 4 + 4 + l + 1);
157         if (!p)
158                 return -ENOMEM;
159
160         p[0] = h;
161         p[1] = 1;
162         p[2] = type;
163         p[3] = 0;
164
165         ((uint32_t*) p)[1] = l;
166         memcpy(p + 8, s, l + 1);
167
168         if (ret)
169                 *ret = (const char*) p + 8;
170
171         return 0;
172 }
173
174 static int message_append_field_signature(
175                 sd_bus_message *m,
176                 uint8_t h,
177                 const char *s,
178                 const char **ret) {
179
180         size_t l;
181         uint8_t *p;
182
183         assert(m);
184
185         l = strlen(s);
186         if (l > 255)
187                 return -EINVAL;
188
189         /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
190         p = message_extend_fields(m, 8, 4 + 1 + l + 1);
191         if (!p)
192                 return -ENOMEM;
193
194         p[0] = h;
195         p[1] = 1;
196         p[2] = SD_BUS_TYPE_SIGNATURE;
197         p[3] = 0;
198         p[4] = l;
199         memcpy(p + 5, s, l + 1);
200
201         if (ret)
202                 *ret = (const char*) p + 5;
203
204         return 0;
205 }
206
207 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
208         uint8_t *p;
209
210         assert(m);
211
212         /* field id byte + signature length + signature 'u' + NUL + value */
213         p = message_extend_fields(m, 8, 4 + 4);
214         if (!p)
215                 return -ENOMEM;
216
217         p[0] = h;
218         p[1] = 1;
219         p[2] = SD_BUS_TYPE_UINT32;
220         p[3] = 0;
221
222         ((uint32_t*) p)[1] = x;
223
224         return 0;
225 }
226
227 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
228         sd_bus_message *m;
229
230         m = malloc0(ALIGN(sizeof(struct sd_bus_message)) + sizeof(struct bus_header));
231         if (!m)
232                 return NULL;
233
234         m->n_ref = 1;
235         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
236
237 #if __BYTE_ORDER == __BIG_ENDIAN
238         m->header->endian = SD_BUS_BIG_ENDIAN;
239 #else
240         m->header->endian = SD_BUS_LITTLE_ENDIAN;
241 #endif
242         m->header->type = type;
243         m->header->version = bus ? bus->message_version : 1;
244
245         return m;
246 }
247
248 int sd_bus_message_new_signal(
249                 sd_bus *bus,
250                 const char *path,
251                 const char *interface,
252                 const char *member,
253                 sd_bus_message **m) {
254
255         sd_bus_message *t;
256         int r;
257
258         if (!path)
259                 return -EINVAL;
260         if (!interface)
261                 return -EINVAL;
262         if (!member)
263                 return -EINVAL;
264         if (!m)
265                 return -EINVAL;
266
267         t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
268         if (!t)
269                 return -ENOMEM;
270
271         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
272         if (r < 0)
273                 goto fail;
274         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
275         if (r < 0)
276                 goto fail;
277         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
278         if (r < 0)
279                 goto fail;
280
281         *m = t;
282         return 0;
283
284 fail:
285         sd_bus_message_unref(t);
286         return r;
287 }
288
289 int sd_bus_message_new_method_call(
290                 sd_bus *bus,
291                 const char *destination,
292                 const char *path,
293                 const char *interface,
294                 const char *member,
295                 sd_bus_message **m) {
296
297         sd_bus_message *t;
298         int r;
299
300         if (!path)
301                 return -EINVAL;
302         if (!member)
303                 return -EINVAL;
304         if (!m)
305                 return -EINVAL;
306
307         t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
308         if (!t)
309                 return -ENOMEM;
310
311         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
312         if (r < 0)
313                 goto fail;
314         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
315         if (r < 0)
316                 goto fail;
317
318         if (interface) {
319                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
320                 if (r < 0)
321                         goto fail;
322         }
323
324         if (destination) {
325                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
326                 if (r < 0)
327                         goto fail;
328         }
329
330         *m = t;
331         return 0;
332
333 fail:
334         message_free(t);
335         return r;
336 }
337
338 static int message_new_reply(
339                 sd_bus *bus,
340                 sd_bus_message *call,
341                 uint8_t type,
342                 sd_bus_message **m) {
343
344         sd_bus_message *t;
345         int r;
346
347         if (!call)
348                 return -EINVAL;
349         if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
350                 return -EINVAL;
351         if (!m)
352                 return -EINVAL;
353
354         t = message_new(bus, type);
355         if (!t)
356                 return -ENOMEM;
357
358         t->reply_serial = BUS_MESSAGE_SERIAL(call);
359
360         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
361         if (r < 0)
362                 goto fail;
363
364         if (call->sender) {
365                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
366                 if (r < 0)
367                         goto fail;
368         }
369
370         t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
371
372         *m = t;
373
374 fail:
375         message_free(t);
376         return r;
377 }
378
379 int sd_bus_message_new_method_return(
380                 sd_bus *bus,
381                 sd_bus_message *call,
382                 sd_bus_message **m) {
383
384         return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
385 }
386
387 int sd_bus_message_new_method_error(
388                 sd_bus *bus,
389                 sd_bus_message *call,
390                 const sd_bus_error *e,
391                 sd_bus_message **m) {
392
393         sd_bus_message *t;
394         int r;
395
396         if (!e)
397                 return -EINVAL;
398         if (!e->name)
399                 return -EINVAL;
400         if (!m)
401                 return -EINVAL;
402
403         r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
404         if (r < 0)
405                 return r;
406
407         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
408         if (r < 0)
409                 goto fail;
410
411         if (e->message) {
412                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
413                 if (r < 0)
414                         goto fail;
415         }
416
417         *m = t;
418         return 0;
419
420 fail:
421         message_free(t);
422         return r;
423 }
424
425 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
426         if (!m)
427                 return NULL;
428
429         assert(m->n_ref > 0);
430         m->n_ref++;
431
432         return m;
433 }
434
435 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
436         if (!m)
437                 return NULL;
438
439         assert(m->n_ref > 0);
440         m->n_ref--;
441
442         if (m->n_ref <= 0)
443                 message_free(m);
444
445         return NULL;
446 }
447
448 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
449         if (!m)
450                 return -EINVAL;
451         if (!type)
452                 return -EINVAL;
453
454         *type = m->header->type;
455         return 0;
456 }
457
458 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
459         if (!m)
460                 return -EINVAL;
461         if (!serial)
462                 return -EINVAL;
463         if (m->header->serial == 0)
464                 return -ENOENT;
465
466         *serial = BUS_MESSAGE_SERIAL(m);
467         return 0;
468 }
469
470 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
471         if (!m)
472                 return -EINVAL;
473         if (!serial)
474                 return -EINVAL;
475         if (m->reply_serial == 0)
476                 return -ENOENT;
477
478         *serial = m->reply_serial;
479         return 0;
480 }
481
482 int sd_bus_message_get_no_reply(sd_bus_message *m) {
483         if (!m)
484                 return -EINVAL;
485
486         return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
487 }
488
489 const char *sd_bus_message_get_path(sd_bus_message *m) {
490         if (!m)
491                 return NULL;
492
493         return m->path;
494 }
495
496 const char *sd_bus_message_get_interface(sd_bus_message *m) {
497         if (!m)
498                 return NULL;
499
500         return m->interface;
501 }
502
503 const char *sd_bus_message_get_member(sd_bus_message *m) {
504         if (!m)
505                 return NULL;
506
507         return m->member;
508 }
509 const char *sd_bus_message_get_destination(sd_bus_message *m) {
510         if (!m)
511                 return NULL;
512
513         return m->destination;
514 }
515
516 const char *sd_bus_message_get_sender(sd_bus_message *m) {
517         if (!m)
518                 return NULL;
519
520         return m->sender;
521 }
522
523 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
524         if (!m)
525                 return NULL;
526
527         if (!sd_bus_error_is_set(&m->error))
528                 return NULL;
529
530         return &m->error;
531 }
532
533 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
534         if (!m)
535                 return -EINVAL;
536         if (!m->uid_valid)
537                 return -ENOENT;
538
539         *uid = m->uid;
540         return 0;
541 }
542
543 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
544         if (!m)
545                 return -EINVAL;
546         if (!m->gid_valid)
547                 return -ENOENT;
548
549         *gid = m->gid;
550         return 0;
551 }
552
553 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
554         if (!m)
555                 return -EINVAL;
556         if (m->pid <= 0)
557                 return -ENOENT;
558
559         *pid = m->pid;
560         return 0;
561 }
562
563 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
564         if (!m)
565                 return -EINVAL;
566         if (m->tid <= 0)
567                 return -ENOENT;
568
569         *tid = m->tid;
570         return 0;
571 }
572
573 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
574         if (!m)
575                 return -EINVAL;
576
577         if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
578                 return 0;
579
580         if (interface && (!m->interface || !streq(m->interface, interface)))
581                 return 0;
582
583         if (member &&  (!m->member || !streq(m->member, member)))
584                 return 0;
585
586         return 1;
587 }
588
589 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
590         if (!m)
591                 return -EINVAL;
592
593         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
594                 return 0;
595
596         if (interface && (!m->interface || !streq(m->interface, interface)))
597                 return 0;
598
599         if (member &&  (!m->member || !streq(m->member, member)))
600                 return 0;
601
602         return 1;
603 }
604
605 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
606         if (!m)
607                 return -EINVAL;
608
609         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
610                 return 0;
611
612         if (name && (!m->error.name || !streq(m->error.name, name)))
613                 return 0;
614
615         return 1;
616 }
617
618 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
619         if (!m)
620                 return -EINVAL;
621         if (m->sealed)
622                 return -EPERM;
623         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
624                 return -EPERM;
625
626         if (b)
627                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
628         else
629                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
630
631         return 0;
632 }
633
634 static struct bus_container *message_get_container(sd_bus_message *m) {
635         assert(m);
636
637         if (m->n_containers == 0)
638                 return &m->root_container;
639
640         assert(m->containers);
641         return m->containers + m->n_containers - 1;
642 }
643
644 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
645         void *p, *o;
646         size_t added;
647         struct bus_container *c;
648
649         assert(m);
650         assert(align > 0);
651
652         o = m->body;
653         added = m->header->body_size;
654
655         p = buffer_extend(&m->body, &m->header->body_size, align, sz);
656         if (!p)
657                 return NULL;
658
659         added = m->header->body_size - added;
660
661         for (c = m->containers; c < m->containers + m->n_containers; c++)
662                 if (c->array_size) {
663                         c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
664                         *c->array_size += added;
665                 }
666
667         if (o != m->body) {
668                 if (m->error.message)
669                         m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
670         }
671
672         m->free_body = true;
673
674         return p;
675 }
676
677 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
678         struct bus_container *c;
679         size_t sz, align;
680         uint32_t k;
681         void *a;
682         char *e = NULL;
683
684         if (!m)
685                 return -EINVAL;
686         if (m->sealed)
687                 return -EPERM;
688         if (!bus_type_is_basic(type))
689                 return -EINVAL;
690
691         c = message_get_container(m);
692
693         if (c->signature && c->signature[c->index]) {
694                 /* Container signature is already set */
695
696                 if (c->signature[c->index] != type)
697                         return -ENXIO;
698         } else {
699                 /* Maybe we can append to the signature? But only if this is the top-level container*/
700                 if (c->enclosing != 0)
701                         return -ENXIO;
702
703                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
704                 if (!e)
705                         return -ENOMEM;
706         }
707
708         switch (type) {
709
710         case SD_BUS_TYPE_STRING:
711         case SD_BUS_TYPE_OBJECT_PATH:
712                 align = 4;
713                 sz = 4 + strlen(p) + 1;
714                 break;
715
716         case SD_BUS_TYPE_SIGNATURE:
717                 align = 1;
718                 sz = 1 + strlen(p) + 1;
719                 break;
720
721         case SD_BUS_TYPE_BOOLEAN:
722                 align = sz = 4;
723
724                 assert_cc(sizeof(int) == sizeof(uint32_t));
725                 memcpy(&k, p, 4);
726                 k = !!k;
727                 p = &k;
728                 break;
729
730         default:
731                 align = bus_type_get_alignment(type);
732                 sz = bus_type_get_size(type);
733                 break;
734         }
735
736         assert(align > 0);
737         assert(sz > 0);
738
739         a = message_extend_body(m, align, sz);
740         if (!a) {
741                 /* Truncate extended signature again */
742                 if (e)
743                         c->signature[c->index] = 0;
744
745                 return -ENOMEM;
746         }
747
748         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
749                 *(uint32_t*) a = sz - 5;
750                 memcpy((uint8_t*) a + 4, p, sz - 4);
751
752                 if (stored)
753                         *stored = (const uint8_t*) a + 4;
754
755         } else if (type == SD_BUS_TYPE_SIGNATURE) {
756                 *(uint8_t*) a = sz - 1;
757                 memcpy((uint8_t*) a + 1, p, sz - 1);
758
759                 if (stored)
760                         *stored = (const uint8_t*) a + 1;
761
762         } else {
763                 memcpy(a, p, sz);
764
765                 if (stored)
766                         *stored = a;
767         }
768
769         if (c->enclosing != SD_BUS_TYPE_ARRAY)
770                 c->index++;
771
772         return 0;
773 }
774
775 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
776         return message_append_basic(m, type, p, NULL);
777 }
778
779 static int bus_message_open_array(
780                 sd_bus_message *m,
781                 struct bus_container *c,
782                 const char *contents,
783                 uint32_t **array_size) {
784
785         unsigned nindex;
786         char *e = NULL;
787         void *a, *b;
788         int alignment;
789         size_t saved;
790
791         assert(m);
792         assert(c);
793         assert(contents);
794         assert(array_size);
795
796         if (!signature_is_single(contents))
797                 return -EINVAL;
798
799         alignment = bus_type_get_alignment(contents[0]);
800         if (alignment < 0)
801                 return alignment;
802
803         if (c->signature && c->signature[c->index]) {
804
805                 /* Verify the existing signature */
806
807                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
808                         return -ENXIO;
809
810                 if (!startswith(c->signature + c->index + 1, contents))
811                         return -ENXIO;
812
813                 nindex = c->index + 1 + strlen(contents);
814         } else {
815                 if (c->enclosing != 0)
816                         return -ENXIO;
817
818                 /* Extend the existing signature */
819
820                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
821                 if (!e)
822                         return -ENOMEM;
823
824                 nindex = e - c->signature;
825         }
826
827         saved = m->header->body_size;
828         a = message_extend_body(m, 4, 4);
829         if (!a) {
830                 /* Truncate extended signature again */
831                 if (e)
832                         c->signature[c->index] = 0;
833
834                 return -ENOMEM;
835         }
836         b = m->body;
837
838         if (!message_extend_body(m, alignment, 0)) {
839                 /* Add alignment between size and first element */
840                 if (e)
841                         c->signature[c->index] = 0;
842
843                 m->header->body_size = saved;
844                 return -ENOMEM;
845         }
846
847         if (c->enclosing != SD_BUS_TYPE_ARRAY)
848                 c->index = nindex;
849
850         /* m->body might have changed so let's readjust a */
851         a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
852         *(uint32_t*) a = 0;
853
854         *array_size = a;
855         return 0;
856 }
857
858 static int bus_message_open_variant(
859                 sd_bus_message *m,
860                 struct bus_container *c,
861                 const char *contents) {
862
863         char *e = NULL;
864         size_t l;
865         void *a;
866
867         assert(m);
868         assert(c);
869         assert(contents);
870
871         if (!signature_is_single(contents))
872                 return -EINVAL;
873
874         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
875                 return -EINVAL;
876
877         if (c->signature && c->signature[c->index]) {
878
879                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
880                         return -ENXIO;
881
882         } else {
883                 if (c->enclosing != 0)
884                         return -ENXIO;
885
886                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
887                 if (!e)
888                         return -ENOMEM;
889         }
890
891         l = strlen(contents);
892         a = message_extend_body(m, 1, 1 + l + 1);
893         if (!a) {
894                 /* Truncate extended signature again */
895                 if (e)
896                         c->signature[c->index] = 0;
897
898                 return -ENOMEM;
899         }
900
901         *(uint8_t*) a = l;
902         memcpy((uint8_t*) a + 1, contents, l + 1);
903
904         if (c->enclosing != SD_BUS_TYPE_ARRAY)
905                 c->index++;
906
907         return 0;
908 }
909
910 static int bus_message_open_struct(
911                 sd_bus_message *m,
912                 struct bus_container *c,
913                 const char *contents) {
914
915         size_t nindex;
916         char *e = NULL;
917
918         assert(m);
919         assert(c);
920         assert(contents);
921
922         if (!signature_is_valid(contents, false))
923                 return -EINVAL;
924
925         if (c->signature && c->signature[c->index]) {
926                 size_t l;
927
928                 l = strlen(contents);
929
930                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
931                     !startswith(c->signature + c->index + 1, contents) ||
932                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
933                         return -ENXIO;
934
935                 nindex = c->index + 1 + l + 1;
936         } else {
937                 if (c->enclosing != 0)
938                         return -ENXIO;
939
940                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
941                 if (!e)
942                         return -ENOMEM;
943
944                 nindex = e - c->signature;
945         }
946
947         /* Align contents to 8 byte boundary */
948         if (!message_extend_body(m, 8, 0)) {
949                 if (e)
950                         c->signature[c->index] = 0;
951
952                 return -ENOMEM;
953         }
954
955         if (c->enclosing != SD_BUS_TYPE_ARRAY)
956                 c->index = nindex;
957
958         return 0;
959 }
960
961 static int bus_message_open_dict_entry(
962                 sd_bus_message *m,
963                 struct bus_container *c,
964                 const char *contents) {
965
966         size_t nindex;
967
968         assert(m);
969         assert(c);
970         assert(contents);
971
972         if (!signature_is_pair(contents))
973                 return -EINVAL;
974
975         if (c->enclosing != SD_BUS_TYPE_ARRAY)
976                 return -ENXIO;
977
978         if (c->signature && c->signature[c->index]) {
979                 size_t l;
980
981                 l = strlen(contents);
982
983                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
984                     !startswith(c->signature + c->index + 1, contents) ||
985                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
986                         return -ENXIO;
987
988                 nindex = c->index + 1 + l + 1;
989         } else
990                 return -ENXIO;
991
992         /* Align contents to 8 byte boundary */
993         if (!message_extend_body(m, 8, 0))
994                 return -ENOMEM;
995
996         if (c->enclosing != SD_BUS_TYPE_ARRAY)
997                 c->index = nindex;
998
999         return 0;
1000 }
1001
1002 int sd_bus_message_open_container(
1003                 sd_bus_message *m,
1004                 char type,
1005                 const char *contents) {
1006
1007         struct bus_container *c, *w;
1008         uint32_t *array_size = NULL;
1009         char *signature;
1010         int r;
1011
1012         if (!m)
1013                 return -EINVAL;
1014         if (m->sealed)
1015                 return -EPERM;
1016         if (!contents)
1017                 return -EINVAL;
1018
1019         /* Make sure we have space for one more container */
1020         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1021         if (!w)
1022                 return -ENOMEM;
1023         m->containers = w;
1024
1025         c = message_get_container(m);
1026
1027         signature = strdup(contents);
1028         if (!signature)
1029                 return -ENOMEM;
1030
1031         if (type == SD_BUS_TYPE_ARRAY)
1032                 r = bus_message_open_array(m, c, contents, &array_size);
1033         else if (type == SD_BUS_TYPE_VARIANT)
1034                 r = bus_message_open_variant(m, c, contents);
1035         else if (type == SD_BUS_TYPE_STRUCT)
1036                 r = bus_message_open_struct(m, c, contents);
1037         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1038                 r = bus_message_open_dict_entry(m, c, contents);
1039         else
1040                 r = -EINVAL;
1041
1042         if (r < 0) {
1043                 free(signature);
1044                 return r;
1045         }
1046
1047         /* OK, let's fill it in */
1048         w += m->n_containers++;
1049         w->enclosing = type;
1050         w->signature = signature;
1051         w->index = 0;
1052         w->array_size = array_size;
1053         w->begin = 0;
1054
1055         return 0;
1056 }
1057
1058 int sd_bus_message_close_container(sd_bus_message *m) {
1059         struct bus_container *c;
1060
1061         if (!m)
1062                 return -EINVAL;
1063         if (m->sealed)
1064                 return -EPERM;
1065         if (m->n_containers <= 0)
1066                 return -EINVAL;
1067
1068         c = message_get_container(m);
1069         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1070                 if (c->signature && c->signature[c->index] != 0)
1071                         return -EINVAL;
1072
1073         free(c->signature);
1074         m->n_containers--;
1075
1076         return 0;
1077 }
1078
1079 static int message_append_ap(
1080                 sd_bus_message *m,
1081                 const char *types,
1082                 va_list ap) {
1083
1084         const char *t;
1085         int r;
1086
1087         assert(m);
1088         assert(types);
1089
1090         for (t = types; *t; t++) {
1091                 switch (*t) {
1092
1093                 case SD_BUS_TYPE_BYTE: {
1094                         uint8_t x;
1095
1096                         x = (uint8_t) va_arg(ap, int);
1097                         r = sd_bus_message_append_basic(m, *t, &x);
1098                         break;
1099                 }
1100
1101                 case SD_BUS_TYPE_BOOLEAN:
1102                 case SD_BUS_TYPE_INT32:
1103                 case SD_BUS_TYPE_UINT32:
1104                 case SD_BUS_TYPE_UNIX_FD: {
1105                         uint32_t x;
1106
1107                         /* We assume a boolean is the same as int32_t */
1108                         assert_cc(sizeof(int32_t) == sizeof(int));
1109
1110                         x = va_arg(ap, uint32_t);
1111                         r = sd_bus_message_append_basic(m, *t, &x);
1112                         break;
1113                 }
1114
1115                 case SD_BUS_TYPE_INT16:
1116                 case SD_BUS_TYPE_UINT16: {
1117                         uint16_t x;
1118
1119                         x = (uint16_t) va_arg(ap, int);
1120                         r = sd_bus_message_append_basic(m, *t, &x);
1121                         break;
1122                 }
1123
1124                 case SD_BUS_TYPE_INT64:
1125                 case SD_BUS_TYPE_UINT64:
1126                 case SD_BUS_TYPE_DOUBLE: {
1127                         uint64_t x;
1128
1129                         x = va_arg(ap, uint64_t);
1130                         r = sd_bus_message_append_basic(m, *t, &x);
1131                         break;
1132                 }
1133
1134                 case SD_BUS_TYPE_STRING:
1135                 case SD_BUS_TYPE_OBJECT_PATH:
1136                 case SD_BUS_TYPE_SIGNATURE: {
1137                         const char *x;
1138
1139                         x = va_arg(ap, const char*);
1140                         r = sd_bus_message_append_basic(m, *t, x);
1141                         break;
1142                 }
1143
1144                 case SD_BUS_TYPE_ARRAY: {
1145                         size_t k;
1146
1147                         r = signature_element_length(t + 1, &k);
1148                         if (r < 0)
1149                                 return r;
1150
1151                         {
1152                                 unsigned i, n;
1153                                 char s[k + 1];
1154
1155                                 memcpy(s, t + 1, k);
1156                                 s[k] = 0;
1157                                 t += k;
1158
1159                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1160                                 if (r < 0)
1161                                         return r;
1162
1163                                 n = va_arg(ap, unsigned);
1164                                 for (i = 0; i < n; i++) {
1165                                         r = message_append_ap(m, s, ap);
1166                                         if (r < 0)
1167                                                 return r;
1168                                 }
1169
1170                                 r = sd_bus_message_close_container(m);
1171                         }
1172
1173                         break;
1174                 }
1175
1176                 case SD_BUS_TYPE_VARIANT: {
1177                         const char *s;
1178
1179                         s = va_arg(ap, const char*);
1180                         if (!s)
1181                                 return -EINVAL;
1182
1183                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1184                         if (r < 0)
1185                                 return r;
1186
1187                         r = message_append_ap(m, s, ap);
1188                         if (r < 0)
1189                                 return r;
1190
1191                         r = sd_bus_message_close_container(m);
1192                         break;
1193                 }
1194
1195                 case SD_BUS_TYPE_STRUCT_BEGIN:
1196                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1197                         size_t k;
1198
1199                         r = signature_element_length(t, &k);
1200                         if (r < 0)
1201                                 return r;
1202
1203                         {
1204                                 char s[k - 1];
1205
1206                                 memcpy(s, t + 1, k - 2);
1207                                 s[k - 2] = 0;
1208
1209                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1210                                 if (r < 0)
1211                                         return r;
1212
1213                                 t += k - 1;
1214
1215                                 r = message_append_ap(m, s, ap);
1216                                 if (r < 0)
1217                                         return r;
1218
1219                                 r = sd_bus_message_close_container(m);
1220                         }
1221
1222                         break;
1223                 }
1224
1225                 default:
1226                         r = -EINVAL;
1227                 }
1228
1229                 if (r < 0)
1230                         return r;
1231         }
1232
1233         return 0;
1234 }
1235
1236 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1237         va_list ap;
1238         int r;
1239
1240         if (!m)
1241                 return -EINVAL;
1242         if (m->sealed)
1243                 return -EPERM;
1244         if (!types)
1245                 return -EINVAL;
1246
1247         va_start(ap, types);
1248         r = message_append_ap(m, types, ap);
1249         va_end(ap);
1250
1251         return r;
1252 }
1253
1254 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1255         size_t k, start, n;
1256
1257         assert(rindex);
1258         assert(align > 0);
1259
1260         start = ALIGN_TO((size_t) *rindex, align);
1261         n = start + nbytes;
1262
1263         if (n > sz)
1264                 return -EBADMSG;
1265
1266         /* Verify that padding is 0 */
1267         for (k = *rindex; k < start; k++)
1268                 if (((const uint8_t*) p)[k] != 0)
1269                         return -EBADMSG;
1270
1271         if (r)
1272                 *r = (uint8_t*) p + start;
1273
1274         *rindex = n;
1275
1276         return 1;
1277 }
1278
1279 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1280         struct bus_container *c;
1281
1282         assert(m);
1283
1284         c = message_get_container(m);
1285         if (!c->array_size)
1286                 return false;
1287
1288         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1289 }
1290
1291 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1292         assert(m);
1293         assert(rindex);
1294         assert(align > 0);
1295
1296         if (message_end_of_array(m, *rindex))
1297                 return 0;
1298
1299         return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1300 }
1301
1302 static bool validate_string(const char *s, size_t l) {
1303         assert(s);
1304
1305         /* Check for NUL chars in the string */
1306         if (memchr(s, 0, l))
1307                 return false;
1308
1309         /* Check for NUL termination */
1310         if (s[l] != 0)
1311                 return false;
1312
1313         /* Check if valid UTF8 */
1314         if (!utf8_is_valid(s))
1315                 return false;
1316
1317         return true;
1318 }
1319
1320 static bool validate_signature(const char *s, size_t l) {
1321         /* Check for NUL chars in the signature */
1322         if (memchr(s, 0, l))
1323                 return false;
1324
1325         /* Check for NUL termination */
1326         if (s[l] != 0)
1327                 return false;
1328
1329         /* Check if valid signature */
1330         if (!signature_is_valid(s, true))
1331                 return false;
1332
1333         return true;
1334 }
1335
1336 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1337         struct bus_container *c;
1338         int r;
1339         void *q;
1340
1341         if (!m)
1342                 return -EINVAL;
1343         if (!m->sealed)
1344                 return -EPERM;
1345         if (!bus_type_is_basic(type))
1346                 return -EINVAL;
1347
1348         c = message_get_container(m);
1349
1350         if (!c->signature || c->signature[c->index] == 0)
1351                 return 0;
1352
1353         if (c->signature[c->index] != type)
1354                 return -ENXIO;
1355
1356         switch (type) {
1357
1358         case SD_BUS_TYPE_STRING:
1359         case SD_BUS_TYPE_OBJECT_PATH: {
1360                 uint32_t l;
1361                 size_t rindex;
1362
1363                 rindex = m->rindex;
1364                 r = message_peek_body(m, &rindex, 4, 4, &q);
1365                 if (r <= 0)
1366                         return r;
1367
1368                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1369                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1370                 if (r < 0)
1371                         return r;
1372                 if (r == 0)
1373                         return -EBADMSG;
1374
1375                 if (!validate_string(q, l))
1376                         return -EBADMSG;
1377
1378                 m->rindex = rindex;
1379                 *(const char**) p = q;
1380                 break;
1381         }
1382
1383         case SD_BUS_TYPE_SIGNATURE: {
1384                 uint8_t l;
1385                 size_t rindex;
1386
1387                 rindex = m->rindex;
1388                 r = message_peek_body(m, &rindex, 1, 1, &q);
1389                 if (r <= 0)
1390                         return r;
1391
1392                 l = *(uint8_t*) q;
1393                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1394                 if (r < 0)
1395                         return r;
1396                 if (r == 0)
1397                         return -EBADMSG;
1398
1399                 if (!validate_signature(q, l))
1400                         return -EBADMSG;
1401
1402                 m->rindex = rindex;
1403                 *(const char**) p = q;
1404                 break;
1405         }
1406
1407         default: {
1408                 size_t sz, align;
1409
1410                 align = bus_type_get_alignment(type);
1411                 sz = bus_type_get_size(type);
1412
1413                 r = message_peek_body(m, &m->rindex, align, sz, &q);
1414                 if (r <= 0)
1415                         return r;
1416
1417                 switch (type) {
1418
1419                 case SD_BUS_TYPE_BYTE:
1420                         *(uint8_t*) p = *(uint8_t*) q;
1421                         break;
1422
1423                 case SD_BUS_TYPE_BOOLEAN:
1424                         *(int*) p = !!*(uint32_t*) q;
1425                         break;
1426
1427                 case SD_BUS_TYPE_INT16:
1428                 case SD_BUS_TYPE_UINT16:
1429                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1430                         break;
1431
1432                 case SD_BUS_TYPE_INT32:
1433                 case SD_BUS_TYPE_UINT32:
1434                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1435                         break;
1436
1437                 case SD_BUS_TYPE_INT64:
1438                 case SD_BUS_TYPE_UINT64:
1439                 case SD_BUS_TYPE_DOUBLE:
1440                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1441                         break;
1442
1443                 default:
1444                         assert_not_reached("Unknown basic type...");
1445                 }
1446
1447                 break;
1448         }
1449         }
1450
1451         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1452                 c->index++;
1453
1454         return 1;
1455 }
1456
1457 static int bus_message_enter_array(
1458                 sd_bus_message *m,
1459                 struct bus_container *c,
1460                 const char *contents,
1461                 uint32_t **array_size) {
1462
1463         size_t rindex;
1464         void *q;
1465         int r, alignment;
1466
1467         assert(m);
1468         assert(c);
1469         assert(contents);
1470         assert(array_size);
1471
1472         if (!signature_is_single(contents))
1473                 return -EINVAL;
1474
1475         alignment = bus_type_get_alignment(contents[0]);
1476         if (alignment < 0)
1477                 return alignment;
1478
1479         if (!c->signature || c->signature[c->index] == 0)
1480                 return 0;
1481
1482         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1483                 return -ENXIO;
1484
1485         if (!startswith(c->signature + c->index + 1, contents))
1486                 return -ENXIO;
1487
1488         rindex = m->rindex;
1489         r = message_peek_body(m, &rindex, 4, 4, &q);
1490         if (r <= 0)
1491                 return r;
1492
1493         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > 67108864)
1494                 return -E2BIG;
1495
1496         r = message_peek_body(m, &rindex, alignment, 0, NULL);
1497         if (r < 0)
1498                 return r;
1499         if (r == 0)
1500                 return -EBADMSG;
1501
1502         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1503                 c->index += 1 + strlen(contents);
1504
1505         m->rindex = rindex;
1506
1507         *array_size = (uint32_t*) q;
1508
1509         return 1;
1510 }
1511
1512 static int bus_message_enter_variant(
1513                 sd_bus_message *m,
1514                 struct bus_container *c,
1515                 const char *contents) {
1516
1517         size_t rindex;
1518         uint8_t l;
1519         void *q;
1520         int r;
1521
1522         assert(m);
1523         assert(c);
1524         assert(contents);
1525
1526         if (!signature_is_single(contents))
1527                 return -EINVAL;
1528
1529         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1530                 return -EINVAL;
1531
1532         if (!c->signature || c->signature[c->index] == 0)
1533                 return 0;
1534
1535         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1536                 return -ENXIO;
1537
1538         rindex = m->rindex;
1539         r = message_peek_body(m, &rindex, 1, 1, &q);
1540         if (r <= 0)
1541                 return r;
1542
1543         l = *(uint8_t*) q;
1544         r = message_peek_body(m, &rindex, 1, l+1, &q);
1545         if (r < 0)
1546                 return r;
1547         if (r == 0)
1548                 return -EBADMSG;
1549
1550         if (!validate_signature(q, l))
1551                 return -EBADMSG;
1552
1553         if (!streq(q, contents))
1554                 return -ENXIO;
1555
1556         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1557                 c->index++;
1558
1559         m->rindex = rindex;
1560
1561         return 1;
1562 }
1563
1564 static int bus_message_enter_struct(
1565                 sd_bus_message *m,
1566                 struct bus_container *c,
1567                 const char *contents) {
1568
1569         size_t l;
1570         int r;
1571
1572         assert(m);
1573         assert(c);
1574         assert(contents);
1575
1576         if (!signature_is_valid(contents, false))
1577                 return -EINVAL;
1578
1579         if (!c->signature || c->signature[c->index] == 0)
1580                 return 0;
1581
1582         l = strlen(contents);
1583
1584         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1585             !startswith(c->signature + c->index + 1, contents) ||
1586             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1587                 return -ENXIO;
1588
1589         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1590         if (r <= 0)
1591                 return r;
1592
1593         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1594                 c->index += 1 + l + 1;
1595
1596         return 1;
1597 }
1598
1599 static int bus_message_enter_dict_entry(
1600                 sd_bus_message *m,
1601                 struct bus_container *c,
1602                 const char *contents) {
1603
1604         size_t l;
1605         int r;
1606
1607         assert(m);
1608         assert(c);
1609         assert(contents);
1610
1611         if (!signature_is_pair(contents))
1612                 return -EINVAL;
1613
1614         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1615                 return -ENXIO;
1616
1617         if (!c->signature || c->signature[c->index] == 0)
1618                 return 0;
1619
1620         l = strlen(contents);
1621
1622         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1623             !startswith(c->signature + c->index + 1, contents) ||
1624             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1625                 return -ENXIO;
1626
1627         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1628         if (r <= 0)
1629                 return r;
1630
1631         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1632                 c->index += 1 + l + 1;
1633
1634         return 1;
1635 }
1636
1637 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1638         struct bus_container *c, *w;
1639         uint32_t *array_size = NULL;
1640         char *signature;
1641         int r;
1642
1643         if (!m)
1644                 return -EINVAL;
1645         if (!m->sealed)
1646                 return -EPERM;
1647         if (!contents)
1648                 return -EINVAL;
1649
1650         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1651         if (!w)
1652                 return -ENOMEM;
1653         m->containers = w;
1654
1655         c = message_get_container(m);
1656
1657         if (!c->signature || c->signature[c->index] == 0)
1658                 return 0;
1659
1660         signature = strdup(contents);
1661         if (!signature)
1662                 return -ENOMEM;
1663
1664         if (type == SD_BUS_TYPE_ARRAY)
1665                 r = bus_message_enter_array(m, c, contents, &array_size);
1666         else if (type == SD_BUS_TYPE_VARIANT)
1667                 r = bus_message_enter_variant(m, c, contents);
1668         else if (type == SD_BUS_TYPE_STRUCT)
1669                 r = bus_message_enter_struct(m, c, contents);
1670         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1671                 r = bus_message_enter_dict_entry(m, c, contents);
1672         else
1673                 r = -EINVAL;
1674
1675         if (r <= 0) {
1676                 free(signature);
1677                 return r;
1678         }
1679
1680         /* OK, let's fill it in */
1681         w += m->n_containers++;
1682         w->enclosing = type;
1683         w->signature = signature;
1684         w->index = 0;
1685         w->array_size = array_size;
1686         w->begin = m->rindex;
1687
1688         return 1;
1689 }
1690
1691 int sd_bus_message_exit_container(sd_bus_message *m) {
1692         struct bus_container *c;
1693
1694         if (!m)
1695                 return -EINVAL;
1696         if (!m->sealed)
1697                 return -EPERM;
1698         if (m->n_containers <= 0)
1699                 return -EINVAL;
1700
1701         c = message_get_container(m);
1702         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1703                 uint32_t l;
1704
1705                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1706                 if (c->begin + l != m->rindex)
1707                         return -EBUSY;
1708
1709         } else {
1710                 if (c->signature && c->signature[c->index] != 0)
1711                         return -EINVAL;
1712         }
1713
1714         free(c->signature);
1715         m->n_containers--;
1716
1717         return 1;
1718 }
1719
1720 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1721         struct bus_container *c;
1722         int r;
1723
1724         if (!m)
1725                 return -EINVAL;
1726         if (!m->sealed)
1727                 return -EPERM;
1728
1729         c = message_get_container(m);
1730
1731         if (!c->signature || c->signature[c->index] == 0)
1732                 goto eof;
1733
1734         if (message_end_of_array(m, m->rindex))
1735                 goto eof;
1736
1737         if (bus_type_is_basic(c->signature[c->index])) {
1738                 if (contents)
1739                         *contents = NULL;
1740                 if (type)
1741                         *type = c->signature[c->index];
1742                 return 1;
1743         }
1744
1745         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1746
1747                 if (contents) {
1748                         size_t l;
1749                         char *sig;
1750
1751                         r = signature_element_length(c->signature+c->index+1, &l);
1752                         if (r < 0)
1753                                 return r;
1754
1755                         sig = strndup(c->signature + c->index + 1, l);
1756                         if (!sig)
1757                                 return -ENOMEM;
1758
1759                         free(m->peeked_signature);
1760                         m->peeked_signature = sig;
1761
1762                         *contents = sig;
1763                 }
1764
1765                 if (type)
1766                         *type = SD_BUS_TYPE_ARRAY;
1767
1768                 return 1;
1769         }
1770
1771         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1772             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1773
1774                 if (contents) {
1775                         size_t l;
1776                         char *sig;
1777
1778                         r = signature_element_length(c->signature+c->index, &l);
1779                         if (r < 0)
1780                                 return r;
1781
1782                         assert(l >= 2);
1783                         sig = strndup(c->signature + c->index + 1, l - 2);
1784                         if (!sig)
1785                                 return -ENOMEM;
1786
1787                         free(m->peeked_signature);
1788                         m->peeked_signature = sig;
1789
1790                         *contents = sig;
1791                 }
1792
1793                 if (type)
1794                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1795
1796                 return 1;
1797         }
1798
1799         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1800                 if (contents) {
1801                         size_t rindex, l;
1802                         void *q;
1803
1804                         rindex = m->rindex;
1805                         r = message_peek_body(m, &rindex, 1, 1, &q);
1806                         if (r < 0)
1807                                 return r;
1808                         if (r == 0)
1809                                 goto eof;
1810
1811                         l = *(uint8_t*) q;
1812                         r = message_peek_body(m, &rindex, 1, l+1, &q);
1813                         if (r < 0)
1814                                 return r;
1815                         if (r == 0)
1816                                 return -EBADMSG;
1817
1818                         if (!validate_signature(q, l))
1819                                 return -EBADMSG;
1820
1821                         *contents = q;
1822                 }
1823
1824                 if (type)
1825                         *type = SD_BUS_TYPE_VARIANT;
1826
1827                 return 1;
1828         }
1829
1830         return -EINVAL;
1831
1832 eof:
1833         if (type)
1834                 *type = c->enclosing;
1835         if (contents)
1836                 *contents = NULL;
1837         return 0;
1838 }
1839
1840 int sd_bus_message_rewind(sd_bus_message *m, bool complete) {
1841         struct bus_container *c;
1842
1843         if (!m)
1844                 return -EINVAL;
1845         if (!m->sealed)
1846                 return -EPERM;
1847
1848         if (complete) {
1849                 reset_containers(m);
1850                 m->rindex = 0;
1851                 m->root_container.index = 0;
1852
1853                 c = message_get_container(m);
1854         } else {
1855                 c = message_get_container(m);
1856
1857                 c->index = 0;
1858                 m->rindex = c->begin;
1859         }
1860
1861         return !isempty(c->signature);
1862 }
1863
1864 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
1865         const char *t;
1866         int r;
1867
1868         assert(m);
1869         assert(types);
1870
1871         for (t = types; *t; t++) {
1872                 switch (*t) {
1873
1874                 case SD_BUS_TYPE_BYTE:
1875                 case SD_BUS_TYPE_BOOLEAN:
1876                 case SD_BUS_TYPE_INT16:
1877                 case SD_BUS_TYPE_UINT16:
1878                 case SD_BUS_TYPE_INT32:
1879                 case SD_BUS_TYPE_UINT32:
1880                 case SD_BUS_TYPE_INT64:
1881                 case SD_BUS_TYPE_UINT64:
1882                 case SD_BUS_TYPE_DOUBLE:
1883                 case SD_BUS_TYPE_STRING:
1884                 case SD_BUS_TYPE_OBJECT_PATH:
1885                 case SD_BUS_TYPE_SIGNATURE: {
1886                         void *p;
1887
1888                         p = va_arg(ap, void*);
1889                         r = sd_bus_message_read_basic(m, *t, p);
1890                         break;
1891                 }
1892
1893                 case SD_BUS_TYPE_ARRAY: {
1894                         size_t k;
1895
1896                         r = signature_element_length(t + 1, &k);
1897                         if (r < 0)
1898                                 return r;
1899
1900                         {
1901                                 unsigned i, n;
1902                                 char s[k + 1];
1903
1904                                 memcpy(s, t + 1, k);
1905                                 s[k] = 0;
1906                                 t += k;
1907
1908                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
1909                                 if (r < 0)
1910                                         return r;
1911                                 if (r == 0)
1912                                         return -ENXIO;
1913
1914                                 n = va_arg(ap, unsigned);
1915                                 for (i = 0; i < n; i++) {
1916                                         r = message_read_ap(m, s, ap);
1917                                         if (r < 0)
1918                                                 return r;
1919                                 }
1920
1921                                 r = sd_bus_message_exit_container(m);
1922                         }
1923
1924                         break;
1925                 }
1926
1927                 case SD_BUS_TYPE_VARIANT: {
1928                         const char *s;
1929
1930                         s = va_arg(ap, const char *);
1931                         if (!s)
1932                                 return -EINVAL;
1933
1934                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
1935                         if (r < 0)
1936                                 return r;
1937                         if (r == 0)
1938                                 return -ENXIO;
1939
1940                         r = message_read_ap(m, s, ap);
1941                         if (r < 0)
1942                                 return r;
1943                         if (r == 0)
1944                                 return -ENXIO;
1945
1946                         r = sd_bus_message_exit_container(m);
1947                         break;
1948                 }
1949
1950                 case SD_BUS_TYPE_STRUCT_BEGIN:
1951                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1952                         size_t k;
1953
1954                         r = signature_element_length(t, &k);
1955                         if (r < 0)
1956                                 return r;
1957
1958                         {
1959                                 char s[k - 1];
1960                                 memcpy(s, t + 1, k - 2);
1961                                 s[k - 2] = 0;
1962
1963                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1964                                 if (r < 0)
1965                                         return r;
1966                                 if (r == 0)
1967                                         return -ENXIO;
1968
1969                                 t += k - 1;
1970
1971                                 r = message_read_ap(m, s, ap);
1972                                 if (r < 0)
1973                                         return r;
1974                                 if (r == 0)
1975                                         return -ENXIO;
1976
1977                                 r = sd_bus_message_exit_container(m);
1978                         }
1979
1980                         break;
1981                 }
1982
1983                 default:
1984                         r = -EINVAL;
1985                 }
1986
1987                 if (r < 0)
1988                         return r;
1989                 if (r == 0)
1990                         return -ENXIO;
1991         }
1992
1993         return 1;
1994 }
1995
1996 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
1997         va_list ap;
1998         int r;
1999
2000         if (!m)
2001                 return -EINVAL;
2002         if (!m->sealed)
2003                 return -EPERM;
2004         if (!types)
2005                 return -EINVAL;
2006
2007         va_start(ap, types);
2008         r = message_read_ap(m, types, ap);
2009         va_end(ap);
2010
2011         return r;
2012 }
2013
2014 int bus_message_parse(sd_bus_message *m) {
2015         assert(m);
2016
2017         if (m->header->version != 1)
2018                 return -EIO;
2019
2020         if (m->header->endian != SD_BUS_BIG_ENDIAN &&
2021             m->header->endian != SD_BUS_LITTLE_ENDIAN)
2022                 return -EIO;
2023
2024         return 0;
2025 }
2026
2027 static void setup_iovec(sd_bus_message *m) {
2028         assert(m);
2029         assert(m->sealed);
2030
2031         m->n_iovec = 0;
2032
2033         m->iovec[m->n_iovec].iov_base = m->header;
2034         m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2035         m->n_iovec++;
2036
2037         if (m->fields) {
2038                 m->iovec[m->n_iovec].iov_base = m->fields;
2039                 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2040                 m->n_iovec++;
2041
2042                 if (m->header->fields_size % 8 != 0) {
2043                         static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2044
2045                         m->iovec[m->n_iovec].iov_base = (void*) padding;
2046                         m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2047                         m->n_iovec++;
2048                 }
2049         }
2050
2051         if (m->body) {
2052                 m->iovec[m->n_iovec].iov_base = m->body;
2053                 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2054                 m->n_iovec++;
2055         }
2056 }
2057
2058 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2059         int r;
2060
2061         assert(m);
2062
2063         if (m->sealed)
2064                 return -EPERM;
2065
2066         if (m->n_containers > 0)
2067                 return -EBADMSG;
2068
2069         /* If there's a non-trivial signature set, then add it in here */
2070         if (!isempty(m->root_container.signature)) {
2071                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, &m->signature);
2072                 if (r < 0)
2073                         return r;
2074         }
2075
2076         if (m->n_fds > 0) {
2077                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2078                 if (r < 0)
2079                         return r;
2080         }
2081
2082         m->header->serial = serial;
2083         m->sealed = true;
2084
2085         setup_iovec(m);
2086
2087         return 0;
2088 }
2089
2090 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2091         if (!m)
2092                 return -EINVAL;
2093         if (!destination)
2094                 return -EINVAL;
2095         if (m->sealed)
2096                 return -EPERM;
2097         if (m->destination)
2098                 return -EEXIST;
2099
2100         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2101 }
2102
2103 int bus_message_dump(sd_bus_message *m) {
2104         unsigned level = 1;
2105         int r;
2106
2107         assert(m);
2108
2109         printf("Message %p\n"
2110                "\tn_ref=%u\n"
2111                "\tendian=%c\n"
2112                "\ttype=%i\n"
2113                "\tflags=%u\n"
2114                "\tversion=%u\n"
2115                "\tserial=%u\n"
2116                "\tfields_size=%u\n"
2117                "\tbody_size=%u\n"
2118                "\tpath=%s\n"
2119                "\tinterface=%s\n"
2120                "\tmember=%s\n"
2121                "\tdestination=%s\n"
2122                "\tsender=%s\n"
2123                "\tsignature=%s\n"
2124                "\treply_serial=%u\n"
2125                "\terror.name=%s\n"
2126                "\terror.message=%s\n"
2127                "\tsealed=%s\n",
2128                m,
2129                m->n_ref,
2130                m->header->endian,
2131                m->header->type,
2132                m->header->flags,
2133                m->header->version,
2134                BUS_MESSAGE_SERIAL(m),
2135                BUS_MESSAGE_FIELDS_SIZE(m),
2136                BUS_MESSAGE_BODY_SIZE(m),
2137                strna(m->path),
2138                strna(m->interface),
2139                strna(m->member),
2140                strna(m->destination),
2141                strna(m->sender),
2142                strna(m->signature),
2143                m->reply_serial,
2144                strna(m->error.name),
2145                strna(m->error.message),
2146                yes_no(m->sealed));
2147
2148         r = sd_bus_message_rewind(m, true);
2149         if (r < 0) {
2150                 log_error("Failed to rewind: %s", strerror(-r));
2151                 return r;
2152         }
2153
2154         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->signature));
2155
2156         for(;;) {
2157                 _cleanup_free_ char *prefix = NULL;
2158                 const char *contents = NULL;
2159                 char type;
2160                 union {
2161                         uint8_t u8;
2162                         uint16_t u16;
2163                         int16_t s16;
2164                         uint32_t u32;
2165                         int32_t s32;
2166                         uint64_t u64;
2167                         int64_t s64;
2168                         double d64;
2169                         const char *string;
2170                         int i;
2171                 } basic;
2172
2173                 r = sd_bus_message_peek_type(m, &type, &contents);
2174                 if (r < 0) {
2175                         log_error("Failed to peek type: %s", strerror(-r));
2176                         return r;
2177                 }
2178                 if (r == 0) {
2179                         if (level <= 1)
2180                                 break;
2181
2182                         r = sd_bus_message_exit_container(m);
2183                         if (r < 0) {
2184                                 log_error("Failed to exit container: %s", strerror(-r));
2185                                 return r;
2186                         }
2187
2188                         level--;
2189
2190                         prefix = strrep("\t", level);
2191                         if (!prefix)
2192                                 return log_oom();
2193
2194                         if (type == SD_BUS_TYPE_ARRAY)
2195                                 printf("%s} END_ARRAY \n", prefix);
2196                         else if (type == SD_BUS_TYPE_VARIANT)
2197                                 printf("%s} END_VARIANT\n", prefix);
2198                         else if (type == SD_BUS_TYPE_STRUCT)
2199                                 printf("%s} END_STRUCT\n", prefix);
2200                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2201                                 printf("%s} END_DICT_ENTRY\n", prefix);
2202
2203                         continue;
2204                 }
2205
2206                 prefix = strrep("\t", level);
2207                 if (!prefix)
2208                         return log_oom();
2209
2210                 if (bus_type_is_container(type) > 0) {
2211                         r = sd_bus_message_enter_container(m, type, contents);
2212                         if (r < 0) {
2213                                 log_error("Failed to enter container: %s", strerror(-r));
2214                                 return r;
2215                         }
2216
2217                         if (type == SD_BUS_TYPE_ARRAY)
2218                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2219                         else if (type == SD_BUS_TYPE_VARIANT)
2220                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2221                         else if (type == SD_BUS_TYPE_STRUCT)
2222                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2223                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2224                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2225
2226                         level ++;
2227
2228                         continue;
2229                 }
2230
2231                 r = sd_bus_message_read_basic(m, type, &basic);
2232                 if (r < 0) {
2233                         log_error("Failed to get basic: %s", strerror(-r));
2234                         return r;
2235                 }
2236
2237                 switch (type) {
2238
2239                 case SD_BUS_TYPE_BYTE:
2240                         printf("%sBYTE: %u\n", prefix, basic.u8);
2241                         break;
2242
2243                 case SD_BUS_TYPE_BOOLEAN:
2244                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2245                         break;
2246
2247                 case SD_BUS_TYPE_INT16:
2248                         printf("%sINT16: %i\n", prefix, basic.s16);
2249                         break;
2250
2251                 case SD_BUS_TYPE_UINT16:
2252                         printf("%sUINT16: %u\n", prefix, basic.u16);
2253                         break;
2254
2255                 case SD_BUS_TYPE_INT32:
2256                         printf("%sINT32: %i\n", prefix, basic.s32);
2257                         break;
2258
2259                 case SD_BUS_TYPE_UINT32:
2260                         printf("%sUINT32: %u\n", prefix, basic.u32);
2261                         break;
2262
2263                 case SD_BUS_TYPE_INT64:
2264                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2265                         break;
2266
2267                 case SD_BUS_TYPE_UINT64:
2268                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2269                         break;
2270
2271                 case SD_BUS_TYPE_DOUBLE:
2272                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
2273                         break;
2274
2275                 case SD_BUS_TYPE_STRING:
2276                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2277                         break;
2278
2279                 case SD_BUS_TYPE_OBJECT_PATH:
2280                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2281                         break;
2282
2283                 case SD_BUS_TYPE_SIGNATURE:
2284                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2285                         break;
2286
2287                 case SD_BUS_TYPE_UNIX_FD:
2288                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
2289                         break;
2290
2291                 default:
2292                         assert_not_reached("Unknown basic type.");
2293                 }
2294         }
2295
2296         printf("} END_MESSAGE\n");
2297         return 0;
2298 }
2299
2300 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2301         size_t total;
2302         unsigned i;
2303         void *p, *e;
2304
2305         assert(m);
2306         assert(buffer);
2307         assert(sz);
2308
2309         for (i = 0, total = 0; i < m->n_iovec; i++)
2310                 total += m->iovec[i].iov_len;
2311
2312         p = malloc(total);
2313         if (!p)
2314                 return -ENOMEM;
2315
2316         for (i = 0, e = p; i < m->n_iovec; i++)
2317                 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2318
2319         *buffer = p;
2320         *sz = total;
2321
2322         return 0;
2323 }