chiark / gitweb /
busctl: show service/session a name belongs to in the list of names
[elogind.git] / src / libsystemd-bus / busctl.c
index 4e2e6aff2606e30265f6b24fc7d341bf23f78834..e962ba3f631e14d26d3382bd580c6c937876eb4d 100644 (file)
 
 static bool arg_no_pager = false;
 static char *arg_address = NULL;
-static bool arg_no_unique = false;
-static bool arg_no_machine = false;
+static bool arg_unique = false;
+static bool arg_acquired = false;
+static bool arg_activatable = false;
+static bool arg_show_machine = false;
 static char **arg_matches = NULL;
 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
 static char *arg_host = NULL;
@@ -53,13 +55,19 @@ static void pager_open_if_enabled(void) {
 
 static int list_bus_names(sd_bus *bus, char **argv) {
         _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
+        _cleanup_free_ char **merged = NULL;
+        _cleanup_hashmap_free_ Hashmap *names = NULL;
         char **i;
         int r;
         size_t max_i = 0;
+        unsigned n = 0;
+        void *v;
+        char *k;
+        Iterator iterator;
 
         assert(bus);
 
-        r = sd_bus_list_names(bus, &acquired, &activatable);
+        r = sd_bus_list_names(bus, (arg_acquired || arg_unique) ? &acquired : NULL, arg_activatable ? &activatable : NULL);
         if (r < 0) {
                 log_error("Failed to list names: %s", strerror(-r));
                 return r;
@@ -67,52 +75,73 @@ static int list_bus_names(sd_bus *bus, char **argv) {
 
         pager_open_if_enabled();
 
-        strv_sort(acquired);
-        strv_sort(activatable);
+        names = hashmap_new(string_hash_func, string_compare_func);
+        if (!names)
+                return log_oom();
 
-        STRV_FOREACH(i, acquired)
+        STRV_FOREACH(i, acquired) {
                 max_i = MAX(max_i, strlen(*i));
 
-        STRV_FOREACH(i, activatable)
+                r = hashmap_put(names, *i, INT_TO_PTR(1));
+                if (r < 0) {
+                        log_error("Failed to add to hashmap: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        STRV_FOREACH(i, activatable) {
                 max_i = MAX(max_i, strlen(*i));
 
-        printf("%-*s %*s %-*s %-*s %-*s",
-               (int) max_i, "NAME", 10, "PID", 15, "PROCESS", 16, "USER", 20, "CONNECTION");
+                r = hashmap_put(names, *i, INT_TO_PTR(2));
+                if (r < 0 && r != -EEXIST) {
+                        log_error("Failed to add to hashmap: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        merged = new(char*, hashmap_size(names) + 1);
+        HASHMAP_FOREACH_KEY(v, k, names, iterator)
+                merged[n++] = k;
+
+        merged[n] = NULL;
+        strv_sort(merged);
 
-        if (!arg_no_machine)
+        printf("%-*s %*s %-*s %-*s %-*s %-*s %-*s",
+               (int) max_i, "NAME", 10, "PID", 15, "PROCESS", 16, "USER", 13, "CONNECTION", 25, "UNIT", 10, "SESSION");
+
+        if (arg_show_machine)
                 puts(" MACHINE");
         else
                 putchar('\n');
 
-        STRV_FOREACH(i, activatable) {
+        STRV_FOREACH(i, merged) {
+                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+                sd_id128_t mid;
 
-                /* Skip the bus driver */
-                if (streq(*i, "org.freedesktop.DBus"))
-                        continue;
+                if (hashmap_get(names, *i) == INT_TO_PTR(2)) {
+                        /* Activatable */
 
-                if (strv_contains(acquired, *i))
+                        printf("%-*s", (int) max_i, *i);
+                        printf("          - -               -                (activatable) -                         -         ");
+                        if (arg_show_machine)
+                                puts(" -");
+                        else
+                                putchar('\n');
                         continue;
 
-                printf("%-*s", (int) max_i, *i);
-                printf("          - -               -                (activation)        ");
-                if (arg_no_machine)
-                        putchar('\n');
-                else
-                        puts(" -");
-        }
+                }
 
-        STRV_FOREACH(i, acquired) {
-                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
-                sd_id128_t mid;
+                if (!arg_unique && (*i)[0] == ':')
+                        continue;
 
-                if (arg_no_unique && (*i)[0] == ':')
+                if (!arg_acquired && (*i)[0] != ':')
                         continue;
 
                 printf("%-*s", (int) max_i, *i);
 
-                r = sd_bus_get_owner(bus, *i, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_UNIQUE_NAME, &creds);
+                r = sd_bus_get_owner(bus, *i, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION, &creds);
                 if (r >= 0) {
-                        const char *unique;
+                        const char *unique, *session, *unit;
                         pid_t pid;
                         uid_t uid;
 
@@ -143,23 +172,40 @@ static int list_bus_names(sd_bus *bus, char **argv) {
 
                         r = sd_bus_creds_get_unique_name(creds, &unique);
                         if (r >= 0)
-                                printf(" %-20s", unique);
+                                printf(" %-13s", unique);
+                        else
+                                fputs(" -            ", stdout);
+
+                        r = sd_bus_creds_get_unit(creds, &unit);
+                        if (r >= 0) {
+                                _cleanup_free_ char *e;
+
+                                e = ellipsize(unit, 25, 100);
+                                if (!e)
+                                        return log_oom();
+
+                                printf(" %-25s", e);
+                        } else
+                                fputs(" -                        ", stdout);
+
+                        r = sd_bus_creds_get_session(creds, &session);
+                        if (r >= 0)
+                                printf(" %-10s", session);
                         else
-                                fputs(" -                   ", stdout);
+                                fputs(" -         ", stdout);
 
                 } else
-                        printf("          - -               -                -                   ");
+                        printf("          - -               -                -             -                         -         ");
 
-                if (arg_no_machine)
-                        putchar('\n');
-                else {
+                if (arg_show_machine) {
                         r = sd_bus_get_owner_machine_id(bus, *i, &mid);
                         if (r >= 0) {
                                 char m[SD_ID128_STRING_MAX];
                                 printf(" %s\n", sd_id128_to_string(mid, m));
                         } else
                                 puts(" -");
-                }
+                } else
+                        putchar('\n');
         }
 
         return 0;
@@ -273,13 +319,15 @@ static int help(void) {
                "  -H --host=[USER@]HOST   Operate on remote host\n"
                "  -M --machine=CONTAINER  Operate on local container\n"
                "     --address=ADDRESS    Connect to bus specified by address\n"
-               "     --no-unique          Only show well-known names\n"
-               "     --no-machine         Don't show machine ID column in list\n"
+               "     --show-machine       Show machine ID column in list\n"
+               "     --unique             Only show unique names\n"
+               "     --acquired           Only show acquired names\n"
+               "     --activatable        Only show activatable names\n"
                "     --match=MATCH        Only show matching messages\n\n"
                "Commands:\n"
                "  list                    List bus names\n"
                "  monitor [SERVICE...]    Show bus traffic\n"
-               "  status ENDPOINT         Show endpoint status\n"
+               "  status NAME             Show name status\n"
                "  help                    Show this help\n",
                program_invocation_short_name);
 
@@ -295,22 +343,26 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_USER,
                 ARG_ADDRESS,
                 ARG_MATCH,
-                ARG_NO_UNIQUE,
-                ARG_NO_MACHINE,
+                ARG_SHOW_MACHINE,
+                ARG_UNIQUE,
+                ARG_ACQUIRED,
+                ARG_ACTIVATABLE
         };
 
         static const struct option options[] = {
-                { "help",       no_argument,       NULL, 'h'            },
-                { "version",    no_argument,       NULL, ARG_VERSION    },
-                { "no-pager",   no_argument,       NULL, ARG_NO_PAGER   },
-                { "system",     no_argument,       NULL, ARG_SYSTEM     },
-                { "user",       no_argument,       NULL, ARG_USER       },
-                { "address",    required_argument, NULL, ARG_ADDRESS    },
-                { "no-unique",  no_argument,       NULL, ARG_NO_UNIQUE  },
-                { "no-machine", no_argument,       NULL, ARG_NO_MACHINE },
-                { "match",      required_argument, NULL, ARG_MATCH      },
-                { "host",       required_argument, NULL, 'H'            },
-                { "machine",    required_argument, NULL, 'M'            },
+                { "help",         no_argument,       NULL, 'h'              },
+                { "version",      no_argument,       NULL, ARG_VERSION      },
+                { "no-pager",     no_argument,       NULL, ARG_NO_PAGER     },
+                { "system",       no_argument,       NULL, ARG_SYSTEM       },
+                { "user",         no_argument,       NULL, ARG_USER         },
+                { "address",      required_argument, NULL, ARG_ADDRESS      },
+                { "show-machine", no_argument,       NULL, ARG_SHOW_MACHINE },
+                { "unique",       no_argument,       NULL, ARG_UNIQUE       },
+                { "acquired",     no_argument,       NULL, ARG_ACQUIRED     },
+                { "activatable",  no_argument,       NULL, ARG_ACTIVATABLE  },
+                { "match",        required_argument, NULL, ARG_MATCH        },
+                { "host",         required_argument, NULL, 'H'              },
+                { "machine",      required_argument, NULL, 'M'              },
                 {},
         };
 
@@ -347,12 +399,20 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_address = optarg;
                         break;
 
-                case ARG_NO_UNIQUE:
-                        arg_no_unique = true;
+                case ARG_SHOW_MACHINE:
+                        arg_show_machine = true;
                         break;
 
-                case ARG_NO_MACHINE:
-                        arg_no_machine = true;
+                case ARG_UNIQUE:
+                        arg_unique = true;
+                        break;
+
+                case ARG_ACQUIRED:
+                        arg_acquired = true;
+                        break;
+
+                case ARG_ACTIVATABLE:
+                        arg_activatable = true;
                         break;
 
                 case ARG_MATCH:
@@ -378,6 +438,9 @@ static int parse_argv(int argc, char *argv[]) {
                 }
         }
 
+        if (!arg_unique && !arg_acquired && !arg_activatable)
+                arg_unique = arg_acquired = arg_activatable = true;
+
         return 1;
 }