1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
22 #include <sys/capability.h>
25 #include "capability.h"
28 #include "bus-message.h"
29 #include "bus-internal.h"
33 static char *indent(unsigned level) {
36 p = new(char, 2 + level + 1);
41 memset(p + 2, '\t', level);
47 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
48 const char *u = NULL, *uu = NULL, *s = NULL;
49 char **cmdline = NULL;
52 uid_t owner, audit_loginuid;
53 uint32_t audit_sessionid;
54 bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
63 "%s%s%sType=%s%s%s Endian=%c Flags=%u Version=%u Serial=%u ",
64 m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
65 m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
66 m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_highlight_off(),
67 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(),
71 BUS_MESSAGE_SERIAL(m));
73 if (m->reply_serial != 0)
74 fprintf(f, " ReplySerial=%u", m->reply_serial);
79 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
81 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
83 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
85 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
87 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
89 if (m->sender || m->destination || m->path || m->interface || m->member)
92 if (sd_bus_error_is_set(&m->error))
95 " ErrorMessage=%s\"%s\"%s\n",
96 ansi_highlight_red(), strna(m->error.name), ansi_highlight_off(),
97 ansi_highlight_red(), strna(m->error.message), ansi_highlight_off());
100 fprintf(f, " PID=%lu", (unsigned long) m->pid);
101 if (m->pid_starttime != 0)
102 fprintf(f, " PIDStartTime=%llu", (unsigned long long) m->pid_starttime);
104 fprintf(f, " TID=%lu", (unsigned long) m->tid);
106 fprintf(f, " UID=%lu", (unsigned long) m->uid);
107 r = sd_bus_message_get_owner_uid(m, &owner);
109 fprintf(f, " OwnerUID=%lu", (unsigned long) owner);
111 fprintf(f, " GID=%lu", (unsigned long) m->gid);
113 if (m->pid != 0 || m->pid_starttime != 0 || m->tid != 0 || m->uid_valid || r >= 0 || m->gid_valid)
116 if (m->monotonic != 0)
117 fprintf(f, " Monotonic=%llu", (unsigned long long) m->monotonic);
118 if (m->realtime != 0)
119 fprintf(f, " Realtime=%llu", (unsigned long long) m->realtime);
121 if (m->monotonic != 0 || m->realtime != 0)
125 fprintf(f, " Exe=%s", m->exe);
127 fprintf(f, " Comm=%s", m->comm);
129 fprintf(f, " TIDComm=%s", m->tid_comm);
131 fprintf(f, " Label=%s", m->label);
133 if (m->exe || m->comm || m->tid_comm || m->label)
136 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
139 fputs(" CommandLine=[", f);
140 STRV_FOREACH(c, cmdline) {
151 fprintf(f, " CGroup=%s\n", m->cgroup);
153 sd_bus_message_get_unit(m, &u);
155 fprintf(f, " Unit=%s", u);
156 sd_bus_message_get_user_unit(m, &uu);
158 fprintf(f, " UserUnit=%s", uu);
159 sd_bus_message_get_session(m, &s);
161 fprintf(f, " Session=%s", s);
162 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0) {
163 audit_loginuid_is_set = true;
164 fprintf(f, " AuditLoginUID=%lu", (unsigned long) audit_loginuid);
166 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0) {
167 audit_sessionid_is_set = true;
168 fprintf(f, " AuditSessionID=%lu", (unsigned long) audit_sessionid);
171 if (u || uu || s || audit_loginuid_is_set || audit_sessionid_is_set)
174 r = sd_bus_message_has_effective_cap(m, 0);
176 unsigned long c, last_cap;
178 fprintf(f, " Capabilities=%s", r ? cap_to_name(0) : "");
180 last_cap = cap_last_cap();
181 for (c = 0; c < last_cap; c++) {
182 r = sd_bus_message_has_effective_cap(m, c);
184 fprintf(f, "|%s", cap_to_name(c));
190 r = sd_bus_message_rewind(m, true);
192 log_error("Failed to rewind: %s", strerror(-r));
196 fprintf(f, " MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
199 _cleanup_free_ char *prefix = NULL;
200 const char *contents = NULL;
215 r = sd_bus_message_peek_type(m, &type, &contents);
217 log_error("Failed to peek type: %s", strerror(-r));
225 r = sd_bus_message_exit_container(m);
227 log_error("Failed to exit container: %s", strerror(-r));
233 prefix = indent(level);
237 fprintf(f, "%s};\n", prefix);
241 prefix = indent(level);
245 if (bus_type_is_container(type) > 0) {
246 r = sd_bus_message_enter_container(m, type, contents);
248 log_error("Failed to enter container: %s", strerror(-r));
252 if (type == SD_BUS_TYPE_ARRAY)
253 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
254 else if (type == SD_BUS_TYPE_VARIANT)
255 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
256 else if (type == SD_BUS_TYPE_STRUCT)
257 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
258 else if (type == SD_BUS_TYPE_DICT_ENTRY)
259 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
266 r = sd_bus_message_read_basic(m, type, &basic);
268 log_error("Failed to get basic: %s", strerror(-r));
276 case SD_BUS_TYPE_BYTE:
277 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
280 case SD_BUS_TYPE_BOOLEAN:
281 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), yes_no(basic.i), ansi_highlight_off());
284 case SD_BUS_TYPE_INT16:
285 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
288 case SD_BUS_TYPE_UINT16:
289 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
292 case SD_BUS_TYPE_INT32:
293 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
296 case SD_BUS_TYPE_UINT32:
297 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
300 case SD_BUS_TYPE_INT64:
301 fprintf(f, "%sINT64 %s%lli%s;\n", prefix, ansi_highlight(), (long long) basic.s64, ansi_highlight_off());
304 case SD_BUS_TYPE_UINT64:
305 fprintf(f, "%sUINT64 %s%llu%s;\n", prefix, ansi_highlight(), (unsigned long long) basic.u64, ansi_highlight_off());
308 case SD_BUS_TYPE_DOUBLE:
309 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
312 case SD_BUS_TYPE_STRING:
313 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
316 case SD_BUS_TYPE_OBJECT_PATH:
317 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
320 case SD_BUS_TYPE_SIGNATURE:
321 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
324 case SD_BUS_TYPE_UNIX_FD:
325 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
329 assert_not_reached("Unknown basic type.");
333 fprintf(f, " };\n\n");