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