]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-dump.c
util-lib: split out allocation calls into alloc-util.[ch]
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-dump.c
CommitLineData
3db0e46b
LP
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
b5efdb8a 22#include "alloc-util.h"
0d39fa9c 23#include "bus-dump.h"
07630cea
LP
24#include "bus-internal.h"
25#include "bus-message.h"
26#include "bus-type.h"
2822da4f 27#include "cap-list.h"
430f0182 28#include "capability-util.h"
0d39fa9c 29#include "fileio.h"
6482f626 30#include "formats-util.h"
8752c575 31#include "locale-util.h"
07630cea
LP
32#include "macro.h"
33#include "string-util.h"
34#include "strv.h"
288a74cc 35#include "terminal-util.h"
07630cea 36#include "util.h"
3db0e46b 37
d55192ad 38static char *indent(unsigned level, unsigned flags) {
f8cfb5f5 39 char *p;
d55192ad 40 unsigned n, i = 0;
f8cfb5f5 41
d55192ad
LP
42 n = 0;
43
44 if (flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY && level > 0)
45 level -= 1;
46
47 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER)
48 n += 2;
49
50 p = new(char, n + level*8 + 1);
f8cfb5f5
LP
51 if (!p)
52 return NULL;
53
d55192ad
LP
54 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
55 p[i++] = ' ';
56 p[i++] = ' ';
57 }
58
59 memset(p + i, ' ', level*8);
60 p[i + level*8] = 0;
f8cfb5f5
LP
61
62 return p;
63}
64
d55192ad 65int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
3db0e46b
LP
66 unsigned level = 1;
67 int r;
3db0e46b
LP
68
69 assert(m);
70
71 if (!f)
72 f = stdout;
73
d55192ad 74 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
3db0e46b 75 fprintf(f,
1fa2f38f 76 "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64,
f8cfb5f5
LP
77 m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
78 m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
1fc464f6
LP
79 m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_normal(),
80 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_normal(),
f8cfb5f5 81 m->header->endian,
3db0e46b 82 m->header->flags,
ca7b42c8 83 m->header->version,
1fa2f38f 84 m->priority);
a009c158
LS
85
86 /* Display synthetic message serial number in a more readable
87 * format than (uint32_t) -1 */
693eb9a2
LP
88 if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
89 fprintf(f, " Cookie=-1");
a009c158 90 else
42c4ebcb 91 fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
3db0e46b 92
693eb9a2 93 if (m->reply_cookie != 0)
42c4ebcb 94 fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
3db0e46b
LP
95
96 fputs("\n", f);
97
98 if (m->sender)
1fc464f6 99 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_normal());
3db0e46b 100 if (m->destination)
1fc464f6 101 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_normal());
3db0e46b 102 if (m->path)
1fc464f6 103 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_normal());
3db0e46b 104 if (m->interface)
1fc464f6 105 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_normal());
3db0e46b 106 if (m->member)
1fc464f6 107 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_normal());
3db0e46b
LP
108
109 if (m->sender || m->destination || m->path || m->interface || m->member)
110 fputs("\n", f);
111
112 if (sd_bus_error_is_set(&m->error))
113 fprintf(f,
114 " ErrorName=%s%s%s"
115 " ErrorMessage=%s\"%s\"%s\n",
1fc464f6
LP
116 ansi_highlight_red(), strna(m->error.name), ansi_normal(),
117 ansi_highlight_red(), strna(m->error.message), ansi_normal());
3db0e46b 118
3db0e46b 119 if (m->monotonic != 0)
de0671ee 120 fprintf(f, " Monotonic="USEC_FMT, m->monotonic);
3db0e46b 121 if (m->realtime != 0)
de0671ee 122 fprintf(f, " Realtime="USEC_FMT, m->realtime);
6a0e376c 123 if (m->seqnum != 0)
de0671ee 124 fprintf(f, " SequenceNumber=%"PRIu64, m->seqnum);
3db0e46b 125
6a0e376c 126 if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
3db0e46b
LP
127 fputs("\n", f);
128
d0b2babf 129 bus_creds_dump(&m->creds, f, true);
3db0e46b
LP
130 }
131
d55192ad 132 r = sd_bus_message_rewind(m, !(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY));
23bbb0de
MS
133 if (r < 0)
134 return log_error_errno(r, "Failed to rewind: %m");
3db0e46b 135
ee04388a
LP
136 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) {
137 _cleanup_free_ char *prefix = NULL;
138
139 prefix = indent(0, flags);
140 if (!prefix)
141 return log_oom();
142
143 fprintf(f, "%sMESSAGE \"%s\" {\n", prefix, strempty(m->root_container.signature));
144 }
3db0e46b 145
f168c273 146 for (;;) {
3db0e46b
LP
147 _cleanup_free_ char *prefix = NULL;
148 const char *contents = NULL;
149 char type;
150 union {
151 uint8_t u8;
152 uint16_t u16;
153 int16_t s16;
154 uint32_t u32;
155 int32_t s32;
156 uint64_t u64;
157 int64_t s64;
158 double d64;
159 const char *string;
160 int i;
161 } basic;
162
163 r = sd_bus_message_peek_type(m, &type, &contents);
23bbb0de
MS
164 if (r < 0)
165 return log_error_errno(r, "Failed to peek type: %m");
3db0e46b
LP
166
167 if (r == 0) {
168 if (level <= 1)
169 break;
170
171 r = sd_bus_message_exit_container(m);
23bbb0de
MS
172 if (r < 0)
173 return log_error_errno(r, "Failed to exit container: %m");
3db0e46b
LP
174
175 level--;
176
d55192ad 177 prefix = indent(level, flags);
3db0e46b
LP
178 if (!prefix)
179 return log_oom();
180
181 fprintf(f, "%s};\n", prefix);
182 continue;
183 }
184
d55192ad 185 prefix = indent(level, flags);
3db0e46b
LP
186 if (!prefix)
187 return log_oom();
188
189 if (bus_type_is_container(type) > 0) {
190 r = sd_bus_message_enter_container(m, type, contents);
23bbb0de
MS
191 if (r < 0)
192 return log_error_errno(r, "Failed to enter container: %m");
3db0e46b
LP
193
194 if (type == SD_BUS_TYPE_ARRAY)
195 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
196 else if (type == SD_BUS_TYPE_VARIANT)
197 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
198 else if (type == SD_BUS_TYPE_STRUCT)
199 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
200 else if (type == SD_BUS_TYPE_DICT_ENTRY)
201 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
202
203 level ++;
204
205 continue;
206 }
207
208 r = sd_bus_message_read_basic(m, type, &basic);
23bbb0de
MS
209 if (r < 0)
210 return log_error_errno(r, "Failed to get basic: %m");
3db0e46b
LP
211
212 assert(r > 0);
213
214 switch (type) {
215
216 case SD_BUS_TYPE_BYTE:
1fc464f6 217 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_normal());
3db0e46b
LP
218 break;
219
220 case SD_BUS_TYPE_BOOLEAN:
1fc464f6 221 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_normal());
3db0e46b
LP
222 break;
223
224 case SD_BUS_TYPE_INT16:
1fc464f6 225 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_normal());
3db0e46b
LP
226 break;
227
228 case SD_BUS_TYPE_UINT16:
1fc464f6 229 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_normal());
3db0e46b
LP
230 break;
231
232 case SD_BUS_TYPE_INT32:
1fc464f6 233 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_normal());
3db0e46b
LP
234 break;
235
236 case SD_BUS_TYPE_UINT32:
1fc464f6 237 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_normal());
3db0e46b
LP
238 break;
239
240 case SD_BUS_TYPE_INT64:
1fc464f6 241 fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_normal());
3db0e46b
LP
242 break;
243
244 case SD_BUS_TYPE_UINT64:
1fc464f6 245 fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_normal());
3db0e46b
LP
246 break;
247
248 case SD_BUS_TYPE_DOUBLE:
1fc464f6 249 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_normal());
3db0e46b
LP
250 break;
251
252 case SD_BUS_TYPE_STRING:
1fc464f6 253 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal());
3db0e46b
LP
254 break;
255
256 case SD_BUS_TYPE_OBJECT_PATH:
1fc464f6 257 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal());
3db0e46b
LP
258 break;
259
260 case SD_BUS_TYPE_SIGNATURE:
1fc464f6 261 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal());
3db0e46b
LP
262 break;
263
264 case SD_BUS_TYPE_UNIX_FD:
1fc464f6 265 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_normal());
3db0e46b
LP
266 break;
267
268 default:
269 assert_not_reached("Unknown basic type.");
270 }
271 }
272
ee04388a
LP
273 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) {
274 _cleanup_free_ char *prefix = NULL;
275
276 prefix = indent(0, flags);
277 if (!prefix)
278 return log_oom();
279
280 fprintf(f, "%s};\n\n", prefix);
281 }
d55192ad 282
3db0e46b
LP
283 return 0;
284}
5b12334d
LP
285
286static void dump_capabilities(
287 sd_bus_creds *c,
288 FILE *f,
289 const char *name,
d0b2babf 290 bool terse,
5b12334d
LP
291 int (*has)(sd_bus_creds *c, int capability)) {
292
293 unsigned long i, last_cap;
294 unsigned n = 0;
295 int r;
296
297 assert(c);
298 assert(f);
299 assert(name);
300 assert(has);
301
302 i = 0;
303 r = has(c, i);
304 if (r < 0)
305 return;
306
d0b2babf 307 fprintf(f, "%s%s=%s", terse ? " " : "", name, terse ? "" : ansi_highlight());
5b12334d
LP
308 last_cap = cap_last_cap();
309
310 for (;;) {
311 if (r > 0) {
5ce70e5b 312
5b12334d
LP
313 if (n > 0)
314 fputc(' ', f);
315 if (n % 4 == 3)
d0b2babf 316 fprintf(f, terse ? "\n " : "\n ");
5b12334d 317
2822da4f 318 fprintf(f, "%s", strna(capability_to_name(i)));
5b12334d
LP
319 n++;
320 }
321
322 i++;
323
324 if (i > last_cap)
325 break;
326
327 r = has(c, i);
328 }
329
330 fputs("\n", f);
d0b2babf
LP
331
332 if (!terse)
1fc464f6 333 fputs(ansi_normal(), f);
5b12334d
LP
334}
335
d0b2babf 336int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
5b12334d
LP
337 uid_t owner, audit_loginuid;
338 uint32_t audit_sessionid;
49b832c5 339 char **cmdline = NULL, **well_known = NULL;
cfeaa44a 340 const char *prefix, *color, *suffix, *s;
329ac4bc 341 int r, q, v, w, z;
5b12334d
LP
342
343 assert(c);
344
345 if (!f)
346 f = stdout;
347
d0b2babf
LP
348 if (terse) {
349 prefix = " ";
350 suffix = "";
351 color = "";
352 } else {
353 const char *off;
354
355 prefix = "";
356 color = ansi_highlight();
357
1fc464f6 358 off = ansi_normal();
63c372cb 359 suffix = strjoina(off, "\n");
d0b2babf
LP
360 }
361
5b12334d 362 if (c->mask & SD_BUS_CREDS_PID)
d0b2babf 363 fprintf(f, "%sPID=%s"PID_FMT"%s", prefix, color, c->pid, suffix);
5b12334d 364 if (c->mask & SD_BUS_CREDS_TID)
d0b2babf 365 fprintf(f, "%sTID=%s"PID_FMT"%s", prefix, color, c->tid, suffix);
cfeaa44a
LP
366 if (c->mask & SD_BUS_CREDS_PPID) {
367 if (c->ppid == 0)
368 fprintf(f, "%sPPID=%sn/a%s", prefix, color, suffix);
369 else
370 fprintf(f, "%sPPID=%s"PID_FMT"%s", prefix, color, c->ppid, suffix);
371 }
4761e880
LP
372 if (c->mask & SD_BUS_CREDS_TTY)
373 fprintf(f, "%sTTY=%s%s%s", prefix, color, strna(c->tty), suffix);
705a415f 374
4761e880 375 if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID|SD_BUS_CREDS_PPID|SD_BUS_CREDS_TTY))))
705a415f
LP
376 fputs("\n", f);
377
5b12334d 378 if (c->mask & SD_BUS_CREDS_UID)
d0b2babf 379 fprintf(f, "%sUID=%s"UID_FMT"%s", prefix, color, c->uid, suffix);
705a415f
LP
380 if (c->mask & SD_BUS_CREDS_EUID)
381 fprintf(f, "%sEUID=%s"UID_FMT"%s", prefix, color, c->euid, suffix);
382 if (c->mask & SD_BUS_CREDS_SUID)
383 fprintf(f, "%sSUID=%s"UID_FMT"%s", prefix, color, c->suid, suffix);
384 if (c->mask & SD_BUS_CREDS_FSUID)
385 fprintf(f, "%sFSUID=%s"UID_FMT"%s", prefix, color, c->fsuid, suffix);
5b12334d
LP
386 r = sd_bus_creds_get_owner_uid(c, &owner);
387 if (r >= 0)
d0b2babf 388 fprintf(f, "%sOwnerUID=%s"UID_FMT"%s", prefix, color, owner, suffix);
5b12334d 389 if (c->mask & SD_BUS_CREDS_GID)
d0b2babf 390 fprintf(f, "%sGID=%s"GID_FMT"%s", prefix, color, c->gid, suffix);
705a415f
LP
391 if (c->mask & SD_BUS_CREDS_EGID)
392 fprintf(f, "%sEGID=%s"GID_FMT"%s", prefix, color, c->egid, suffix);
393 if (c->mask & SD_BUS_CREDS_SGID)
394 fprintf(f, "%sSGID=%s"GID_FMT"%s", prefix, color, c->sgid, suffix);
395 if (c->mask & SD_BUS_CREDS_FSGID)
396 fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
397
02581590
LP
398 if (c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
399 unsigned i;
400
401 fprintf(f, "%sSupplementaryGIDs=%s", prefix, color);
402 for (i = 0; i < c->n_supplementary_gids; i++)
403 fprintf(f, "%s" GID_FMT, i > 0 ? " " : "", c->supplementary_gids[i]);
404 fprintf(f, "%s", suffix);
405 }
406
705a415f 407 if (terse && ((c->mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
02581590
LP
408 SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
409 SD_BUS_CREDS_SUPPLEMENTARY_GIDS)) || r >= 0))
5b12334d
LP
410 fputs("\n", f);
411
5b12334d 412 if (c->mask & SD_BUS_CREDS_COMM)
d0b2babf 413 fprintf(f, "%sComm=%s%s%s", prefix, color, c->comm, suffix);
5b12334d 414 if (c->mask & SD_BUS_CREDS_TID_COMM)
d0b2babf 415 fprintf(f, "%sTIDComm=%s%s%s", prefix, color, c->tid_comm, suffix);
5cf4f2d1 416 if (c->mask & SD_BUS_CREDS_EXE)
cfeaa44a 417 fprintf(f, "%sExe=%s%s%s", prefix, color, strna(c->exe), suffix);
14008e4e 418
d0b2babf 419 if (terse && (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)))
14008e4e
LP
420 fputs("\n", f);
421
cfeaa44a
LP
422 r = sd_bus_creds_get_cmdline(c, &cmdline);
423 if (r >= 0) {
5b12334d
LP
424 char **i;
425
d0b2babf 426 fprintf(f, "%sCommandLine=%s", prefix, color);
5b12334d
LP
427 STRV_FOREACH(i, cmdline) {
428 if (i != cmdline)
429 fputc(' ', f);
430
431 fputs(*i, f);
432 }
433
d0b2babf 434 fprintf(f, "%s", suffix);
cfeaa44a
LP
435 } else if (r != -ENODATA)
436 fprintf(f, "%sCommandLine=%sn/a%s", prefix, color, suffix);
5b12334d 437
5cf4f2d1
LP
438 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
439 fprintf(f, "%sLabel=%s%s%s", prefix, color, c->label, suffix);
440 if (c->mask & SD_BUS_CREDS_DESCRIPTION)
441 fprintf(f, "%sDescription=%s%s%s", prefix, color, c->description, suffix);
442
443 if (terse && (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_DESCRIPTION)))
444 fputs("\n", f);
445
5b12334d 446 if (c->mask & SD_BUS_CREDS_CGROUP)
d0b2babf 447 fprintf(f, "%sCGroup=%s%s%s", prefix, color, c->cgroup, suffix);
cfeaa44a
LP
448 s = NULL;
449 r = sd_bus_creds_get_unit(c, &s);
450 if (r != -ENODATA)
451 fprintf(f, "%sUnit=%s%s%s", prefix, color, strna(s), suffix);
452 s = NULL;
cfeaa44a
LP
453 v = sd_bus_creds_get_slice(c, &s);
454 if (v != -ENODATA)
455 fprintf(f, "%sSlice=%s%s%s", prefix, color, strna(s), suffix);
456 s = NULL;
329ac4bc
LP
457 q = sd_bus_creds_get_user_unit(c, &s);
458 if (q != -ENODATA)
459 fprintf(f, "%sUserUnit=%s%s%s", prefix, color, strna(s), suffix);
460 s = NULL;
461 w = sd_bus_creds_get_user_slice(c, &s);
cfeaa44a 462 if (w != -ENODATA)
329ac4bc
LP
463 fprintf(f, "%sUserSlice=%s%s%s", prefix, color, strna(s), suffix);
464 s = NULL;
465 z = sd_bus_creds_get_session(c, &s);
466 if (z != -ENODATA)
cfeaa44a
LP
467 fprintf(f, "%sSession=%s%s%s", prefix, color, strna(s), suffix);
468
329ac4bc 469 if (terse && ((c->mask & SD_BUS_CREDS_CGROUP) || r != -ENODATA || q != -ENODATA || v != -ENODATA || w != -ENODATA || z != -ENODATA))
5b12334d
LP
470 fputs("\n", f);
471
cfeaa44a
LP
472 r = sd_bus_creds_get_audit_login_uid(c, &audit_loginuid);
473 if (r >= 0)
d0b2babf 474 fprintf(f, "%sAuditLoginUID=%s"UID_FMT"%s", prefix, color, audit_loginuid, suffix);
cfeaa44a
LP
475 else if (r != -ENODATA)
476 fprintf(f, "%sAuditLoginUID=%sn/a%s", prefix, color, suffix);
477 q = sd_bus_creds_get_audit_session_id(c, &audit_sessionid);
478 if (q >= 0)
d0b2babf 479 fprintf(f, "%sAuditSessionID=%s%"PRIu32"%s", prefix, color, audit_sessionid, suffix);
cfeaa44a
LP
480 else if (q != -ENODATA)
481 fprintf(f, "%sAuditSessionID=%sn/a%s", prefix, color, suffix);
5b12334d 482
cfeaa44a 483 if (terse && (r != -ENODATA || q != -ENODATA))
5b12334d
LP
484 fputs("\n", f);
485
49b832c5 486 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
d0b2babf 487 fprintf(f, "%sUniqueName=%s%s%s", prefix, color, c->unique_name, suffix);
49b832c5
LP
488
489 if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
490 char **i;
491
d0b2babf 492 fprintf(f, "%sWellKnownNames=%s", prefix, color);
49b832c5
LP
493 STRV_FOREACH(i, well_known) {
494 if (i != well_known)
495 fputc(' ', f);
496
497 fputs(*i, f);
498 }
499
d0b2babf 500 fprintf(f, "%s", suffix);
49b832c5
LP
501 }
502
d0b2babf 503 if (terse && (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known))
3310dfd5
LP
504 fputc('\n', f);
505
d0b2babf
LP
506 dump_capabilities(c, f, "EffectiveCapabilities", terse, sd_bus_creds_has_effective_cap);
507 dump_capabilities(c, f, "PermittedCapabilities", terse, sd_bus_creds_has_permitted_cap);
508 dump_capabilities(c, f, "InheritableCapabilities", terse, sd_bus_creds_has_inheritable_cap);
509 dump_capabilities(c, f, "BoundingCapabilities", terse, sd_bus_creds_has_bounding_cap);
5b12334d
LP
510
511 return 0;
512}
1f70b087
LP
513
514/*
515 * For details about the file format, see:
516 *
517 * http://wiki.wireshark.org/Development/LibpcapFileFormat
518 */
519
520typedef struct _packed_ pcap_hdr_s {
521 uint32_t magic_number; /* magic number */
522 uint16_t version_major; /* major version number */
523 uint16_t version_minor; /* minor version number */
524 int32_t thiszone; /* GMT to local correction */
525 uint32_t sigfigs; /* accuracy of timestamps */
526 uint32_t snaplen; /* max length of captured packets, in octets */
527 uint32_t network; /* data link type */
528} pcap_hdr_t ;
529
530typedef struct _packed_ pcaprec_hdr_s {
531 uint32_t ts_sec; /* timestamp seconds */
532 uint32_t ts_usec; /* timestamp microseconds */
533 uint32_t incl_len; /* number of octets of packet saved in file */
534 uint32_t orig_len; /* actual length of packet */
535} pcaprec_hdr_t;
536
537int bus_pcap_header(size_t snaplen, FILE *f) {
538
539 pcap_hdr_t hdr = {
540 .magic_number = 0xa1b2c3d4U,
541 .version_major = 2,
542 .version_minor = 4,
543 .thiszone = 0, /* UTC */
544 .sigfigs = 0,
545 .network = 231, /* D-Bus */
546 };
547
548 if (!f)
549 f = stdout;
550
551 assert(snaplen > 0);
552 assert((size_t) (uint32_t) snaplen == snaplen);
553
554 hdr.snaplen = (uint32_t) snaplen;
555
556 fwrite(&hdr, 1, sizeof(hdr), f);
1f70b087 557
dacd6cee 558 return fflush_and_check(f);
1f70b087
LP
559}
560
561int bus_message_pcap_frame(sd_bus_message *m, size_t snaplen, FILE *f) {
562 struct bus_body_part *part;
563 pcaprec_hdr_t hdr = {};
564 struct timeval tv;
565 unsigned i;
566 size_t w;
567
568 if (!f)
569 f = stdout;
570
571 assert(m);
572 assert(snaplen > 0);
573 assert((size_t) (uint32_t) snaplen == snaplen);
574
575 if (m->realtime != 0)
576 timeval_store(&tv, m->realtime);
577 else
578 assert_se(gettimeofday(&tv, NULL) >= 0);
579
580 hdr.ts_sec = tv.tv_sec;
581 hdr.ts_usec = tv.tv_usec;
582 hdr.orig_len = BUS_MESSAGE_SIZE(m);
583 hdr.incl_len = MIN(hdr.orig_len, snaplen);
584
585 /* write the pcap header */
586 fwrite(&hdr, 1, sizeof(hdr), f);
587
588 /* write the dbus header */
589 w = MIN(BUS_MESSAGE_BODY_BEGIN(m), snaplen);
590 fwrite(m->header, 1, w, f);
591 snaplen -= w;
592
593 /* write the dbus body */
594 MESSAGE_FOREACH_PART(part, i, m) {
595 if (snaplen <= 0)
596 break;
597
598 w = MIN(part->size, snaplen);
599 fwrite(part->data, 1, w, f);
600 snaplen -= w;
601 }
602
dacd6cee 603 return fflush_and_check(f);
1f70b087 604}