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