]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-dump.c
sd-event: fix comparison functions
[thirdparty/systemd.git] / src / libsystemd-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
22#include <sys/capability.h>
23
24#include "util.h"
25#include "capability.h"
26#include "strv.h"
27
28#include "bus-message.h"
29#include "bus-internal.h"
30#include "bus-type.h"
31#include "bus-dump.h"
32
f8cfb5f5
LP
33static char *indent(unsigned level) {
34 char *p;
35
36 p = new(char, 2 + level + 1);
37 if (!p)
38 return NULL;
39
40 p[0] = p[1] = ' ';
41 memset(p + 2, '\t', level);
42 p[2 + level] = 0;
43
44 return p;
45}
46
3db0e46b
LP
47int 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;
50 unsigned level = 1;
51 int r;
52 uid_t owner, audit_loginuid;
53 uint32_t audit_sessionid;
f8cfb5f5 54 bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
3db0e46b
LP
55
56 assert(m);
57
58 if (!f)
59 f = stdout;
60
61 if (with_header) {
62 fprintf(f,
f8cfb5f5
LP
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(),
3db0e46b 67 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(),
f8cfb5f5 68 m->header->endian,
3db0e46b
LP
69 m->header->flags,
70 m->header->version,
71 BUS_MESSAGE_SERIAL(m));
72
73 if (m->reply_serial != 0)
74 fprintf(f, " ReplySerial=%u", m->reply_serial);
75
76 fputs("\n", f);
77
78 if (m->sender)
79 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
80 if (m->destination)
81 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
82 if (m->path)
83 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
84 if (m->interface)
85 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
86 if (m->member)
87 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
88
89 if (m->sender || m->destination || m->path || m->interface || m->member)
90 fputs("\n", f);
91
92 if (sd_bus_error_is_set(&m->error))
93 fprintf(f,
94 " ErrorName=%s%s%s"
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());
98
99 if (m->pid != 0)
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);
103 if (m->tid != 0)
104 fprintf(f, " TID=%lu", (unsigned long) m->tid);
105 if (m->uid_valid)
106 fprintf(f, " UID=%lu", (unsigned long) m->uid);
107 r = sd_bus_message_get_owner_uid(m, &owner);
108 if (r >= 0)
109 fprintf(f, " OwnerUID=%lu", (unsigned long) owner);
110 if (m->gid_valid)
111 fprintf(f, " GID=%lu", (unsigned long) m->gid);
112
113 if (m->pid != 0 || m->pid_starttime != 0 || m->tid != 0 || m->uid_valid || r >= 0 || m->gid_valid)
114 fputs("\n", f);
115
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);
120
121 if (m->monotonic != 0 || m->realtime != 0)
122 fputs("\n", f);
123
124 if (m->exe)
125 fprintf(f, " Exe=%s", m->exe);
126 if (m->comm)
127 fprintf(f, " Comm=%s", m->comm);
128 if (m->tid_comm)
129 fprintf(f, " TIDComm=%s", m->tid_comm);
130 if (m->label)
131 fprintf(f, " Label=%s", m->label);
132
133 if (m->exe || m->comm || m->tid_comm || m->label)
134 fputs("\n", f);
135
136 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
137 char **c;
138
139 fputs(" CommandLine=[", f);
140 STRV_FOREACH(c, cmdline) {
141 if (c != cmdline)
142 fputc(' ', f);
143
144 fputs(*c, f);
145 }
146
147 fputs("]\n", f);
148 }
149
150 if (m->cgroup)
151 fprintf(f, " CGroup=%s\n", m->cgroup);
152
153 sd_bus_message_get_unit(m, &u);
154 if (u)
155 fprintf(f, " Unit=%s", u);
156 sd_bus_message_get_user_unit(m, &uu);
157 if (uu)
158 fprintf(f, " UserUnit=%s", uu);
159 sd_bus_message_get_session(m, &s);
160 if (s)
161 fprintf(f, " Session=%s", s);
f8cfb5f5
LP
162 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0) {
163 audit_loginuid_is_set = true;
3db0e46b 164 fprintf(f, " AuditLoginUID=%lu", (unsigned long) audit_loginuid);
f8cfb5f5
LP
165 }
166 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0) {
167 audit_sessionid_is_set = true;
3db0e46b 168 fprintf(f, " AuditSessionID=%lu", (unsigned long) audit_sessionid);
f8cfb5f5 169 }
3db0e46b 170
f8cfb5f5 171 if (u || uu || s || audit_loginuid_is_set || audit_sessionid_is_set)
3db0e46b
LP
172 fputs("\n", f);
173
174 r = sd_bus_message_has_effective_cap(m, 0);
175 if (r >= 0) {
176 unsigned long c, last_cap;
177
178 fprintf(f, " Capabilities=%s", r ? cap_to_name(0) : "");
179
180 last_cap = cap_last_cap();
181 for (c = 0; c < last_cap; c++) {
182 r = sd_bus_message_has_effective_cap(m, c);
183 if (r > 0)
184 fprintf(f, "|%s", cap_to_name(c));
185 }
f8cfb5f5 186 fputs("\n", f);
3db0e46b
LP
187 }
188 }
189
190 r = sd_bus_message_rewind(m, true);
191 if (r < 0) {
192 log_error("Failed to rewind: %s", strerror(-r));
193 return r;
194 }
195
f8cfb5f5 196 fprintf(f, " MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3db0e46b
LP
197
198 for(;;) {
199 _cleanup_free_ char *prefix = NULL;
200 const char *contents = NULL;
201 char type;
202 union {
203 uint8_t u8;
204 uint16_t u16;
205 int16_t s16;
206 uint32_t u32;
207 int32_t s32;
208 uint64_t u64;
209 int64_t s64;
210 double d64;
211 const char *string;
212 int i;
213 } basic;
214
215 r = sd_bus_message_peek_type(m, &type, &contents);
216 if (r < 0) {
217 log_error("Failed to peek type: %s", strerror(-r));
218 return r;
219 }
220
221 if (r == 0) {
222 if (level <= 1)
223 break;
224
225 r = sd_bus_message_exit_container(m);
226 if (r < 0) {
227 log_error("Failed to exit container: %s", strerror(-r));
228 return r;
229 }
230
231 level--;
232
f8cfb5f5 233 prefix = indent(level);
3db0e46b
LP
234 if (!prefix)
235 return log_oom();
236
237 fprintf(f, "%s};\n", prefix);
238 continue;
239 }
240
f8cfb5f5 241 prefix = indent(level);
3db0e46b
LP
242 if (!prefix)
243 return log_oom();
244
245 if (bus_type_is_container(type) > 0) {
246 r = sd_bus_message_enter_container(m, type, contents);
247 if (r < 0) {
248 log_error("Failed to enter container: %s", strerror(-r));
249 return r;
250 }
251
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);
260
261 level ++;
262
263 continue;
264 }
265
266 r = sd_bus_message_read_basic(m, type, &basic);
267 if (r < 0) {
268 log_error("Failed to get basic: %s", strerror(-r));
269 return r;
270 }
271
272 assert(r > 0);
273
274 switch (type) {
275
276 case SD_BUS_TYPE_BYTE:
277 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
278 break;
279
280 case SD_BUS_TYPE_BOOLEAN:
281 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), yes_no(basic.i), ansi_highlight_off());
282 break;
283
284 case SD_BUS_TYPE_INT16:
285 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
286 break;
287
288 case SD_BUS_TYPE_UINT16:
289 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
290 break;
291
292 case SD_BUS_TYPE_INT32:
293 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
294 break;
295
296 case SD_BUS_TYPE_UINT32:
297 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
298 break;
299
300 case SD_BUS_TYPE_INT64:
301 fprintf(f, "%sINT64 %s%lli%s;\n", prefix, ansi_highlight(), (long long) basic.s64, ansi_highlight_off());
302 break;
303
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());
306 break;
307
308 case SD_BUS_TYPE_DOUBLE:
309 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
310 break;
311
312 case SD_BUS_TYPE_STRING:
313 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
314 break;
315
316 case SD_BUS_TYPE_OBJECT_PATH:
317 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
318 break;
319
320 case SD_BUS_TYPE_SIGNATURE:
321 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
322 break;
323
324 case SD_BUS_TYPE_UNIX_FD:
325 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
326 break;
327
328 default:
329 assert_not_reached("Unknown basic type.");
330 }
331 }
332
f8cfb5f5 333 fprintf(f, " };\n\n");
3db0e46b
LP
334 return 0;
335}