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