return 0;
}
+void dot_dump_unique_name(sd_bus *bus, char *name, Hashmap *hashmap_wkn, FILE *f, sd_bus_message *m) {
+ int r;
+ bool update = false;
+ int obtained;
+ char *uname;
+ char *contents = NULL;
+ char type;
+ union {
+ uint8_t u8;
+ uint16_t u16;
+ int16_t s16;
+ uint32_t u32;
+ int32_t s32;
+ uint64_t u64;
+ int64_t s64;
+ double d64;
+ const char *string;
+ int i;
+ } basic;
+ sd_bus_creds *creds = NULL;
+
+ if (m->member && !strcmp(m->member, "NameOwnerChanged")) {
+
+ r = sd_bus_message_peek_type(m, &type, &contents);
+
+ if (r > 0 && bus_type_is_container(type) <= 0) {
+ if (r >= 0)
+ r = sd_bus_message_read_basic(m, type, &basic);
+
+ if (r >= 0) {
+ char *free_name = hashmap_get(hashmap_wkn, basic.string);
+ free(free_name);
+ update = true;
+ }
+ }
+ }
+
+ int x, y;
+
+ if (!f)
+ f = stdout;
+
+ if (!name)
+ return;
+
+ if (name[0] == ':')
+ return;
+
+ obtained = hashmap_get(hashmap_wkn, name);
+
+ if (obtained && !update)
+ return;
+
+ r = sd_bus_get_name_creds(bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds);
+
+ if (r >= 0)
+ r = sd_bus_creds_get_unique_name(creds, &uname);
+
+ if (r < 0)
+ return;
+
+ fprintf(f, "\t\"%s\"->\"%s\" [ color = blue, penwidth = 4];\n", name, uname);
+
+ if (update)
+ hashmap_update(hashmap_wkn, name, strdup(uname));
+ else
+ hashmap_put(hashmap_wkn, strdup(name), strdup(uname));
+
+}
+
+
int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
unsigned level = 1;
int r;
static bool arg_pid = false;
static bool arg_dot = false;
static bool monitor_run_condi = true;
+static bool arg_well_known_names;
#define NAME_IS_ACQUIRED INT_TO_PTR(1)
#define NAME_IS_ACTIVATABLE INT_TO_PTR(2)
return 0;
}
-static int message_dump(sd_bus_message *m, FILE *f) {
+static int message_dump(sd_bus_message *m, FILE *f, Hashmap *hashmap_wkn, sd_bus *bus) {
return bus_message_dump(m, f, BUS_MESSAGE_DUMP_WITH_HEADER);
}
-static int message_pcap(sd_bus_message *m, FILE *f) {
+static int message_pcap(sd_bus_message *m, FILE *f, Hashmap *hashmap_wkn, sd_bus *bus) {
return bus_message_pcap_frame(m, arg_snaplen, f);
}
-static int message_dot(sd_bus_message *m, FILE *f) {
+static int message_dot(sd_bus_message *m, FILE *f, Hashmap *hashmap_wkn, sd_bus *bus) {
+
+ if (arg_well_known_names){
+
+ dot_dump_unique_name(bus, sd_bus_message_get_sender(m), hashmap_wkn, f, m);
+ dot_dump_unique_name(bus, sd_bus_message_get_destination(m), hashmap_wkn, f, m);
+ }
+
return bus_message_dot_dump(m, f);
}
-static bool check_pid(sd_bus *bus, Hashmap *hashmap_pids, char *name, int compare_pid, sd_bus_message *m) {
+static bool check_pid(sd_bus *bus, Hashmap *hashmap_pids, char *name, int compare_pid) {
pid_t pid;
sd_bus_creds *creds = NULL;
int r;
}
-static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FILE *f)) {
+static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FILE *f, Hashmap *hashmap_wkn, sd_bus *bus)) {
bool added_something = false;
char **i;
int r;
bool receiver_pid_match;
bool sender_pid_match;
+ sd_bus_creds *creds = NULL;
_cleanup_hashmap_free_ Hashmap *hashmap_pids = NULL;
+ _cleanup_hashmap_free_ Hashmap *hashmap_names = NULL;
+ _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
hashmap_pids = hashmap_new(&string_hash_ops);
+ hashmap_names = hashmap_new(&string_hash_ops);
STRV_FOREACH(i, argv+1) {
_cleanup_free_ char *m = NULL;
-
if (!service_name_is_valid(*i)) {
log_error("Invalid service name '%s'", *i);
return -EINVAL;
return log_error_errno(r, "Failed to process bus: %m");
if (m) {
+
if (arg_sender_pid != 0) {
sender_pid_match = check_pid(
bus,
hashmap_pids,
sd_bus_message_get_sender(m),
- arg_sender_pid,
- m);
+ arg_sender_pid);
}
if (arg_receiver_pid != 0) {
bus,
hashmap_pids,
sd_bus_message_get_destination(m),
- arg_receiver_pid,
- m);
+ arg_receiver_pid);
}
if ((!arg_pid && receiver_pid_match && sender_pid_match) || (arg_pid && (receiver_pid_match || sender_pid_match))) {
- dump(m, stdout);
+ dump(m, stdout, hashmap_names, bus);
}
fflush(stdout);
" Only show message with sender pid equals SENDER_PID\n"
" --receiver-pid=RECEIVER_PID\n"
" Only show message with receiver pid equals RECEIVER_PID\n"
+ " --well-known-names=BOOL \n"
+ " Show well know names connected to unique names on graph\n"
"Commands:\n"
" list List bus names\n"
" status [SERVICE] Show bus service, process or bus owner credentials\n"
ARG_PID,
ARG_SENDER_PID,
ARG_RECEIVER_PID,
+ ARG_WELL_KNOWN_NAMES,
};
static const struct option options[] = {
{ "pid", required_argument, NULL, ARG_PID},
{ "sender-pid", required_argument, NULL, ARG_SENDER_PID},
{ "receiver-pid", required_argument, NULL, ARG_RECEIVER_PID},
+ { "well-known-names", required_argument, NULL, ARG_WELL_KNOWN_NAMES},
{},
};
return 0;
break;
+ case ARG_WELL_KNOWN_NAMES:
+ arg_well_known_names = parse_boolean(optarg);
+ break;
+
case '?':
return -EINVAL;