chiark / gitweb /
loginctl,shell-completions: fix listing of sessions/users/seats
[elogind.git] / src / login / loginctl.c
index f96a568610b07e78be5bb3784842ab064f875b9b..7e64066479f0ad3241d22457d07205bc12c24294 100644 (file)
@@ -45,6 +45,7 @@ static char **arg_property = NULL;
 static bool arg_all = false;
 static bool arg_full = false;
 static bool arg_no_pager = false;
+static bool arg_legend = true;
 static const char *arg_kill_who = NULL;
 static int arg_signal = SIGTERM;
 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
@@ -99,7 +100,8 @@ static int list_sessions(sd_bus *bus, char **args, unsigned n) {
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        printf("%10s %10s %-16s %-16s\n", "SESSION", "UID", "USER", "SEAT");
+        if (arg_legend)
+                printf("%10s %10s %-16s %-16s\n", "SESSION", "UID", "USER", "SEAT");
 
         while ((r = sd_bus_message_read(reply, "(susso)", &id, &uid, &user, &seat, &object)) > 0) {
                 printf("%10s %10u %-16s %-16s\n", id, (unsigned) uid, user, seat);
@@ -108,7 +110,8 @@ static int list_sessions(sd_bus *bus, char **args, unsigned n) {
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        printf("\n%u sessions listed.\n", k);
+        if (arg_legend)
+                printf("\n%u sessions listed.\n", k);
 
         return 0;
 }
@@ -140,7 +143,8 @@ static int list_users(sd_bus *bus, char **args, unsigned n) {
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        printf("%10s %-16s\n", "UID", "USER");
+        if (arg_legend)
+                printf("%10s %-16s\n", "UID", "USER");
 
         while ((r = sd_bus_message_read(reply, "(uso)", &uid, &user, &object)) > 0) {
                 printf("%10u %-16s\n", (unsigned) uid, user);
@@ -149,7 +153,8 @@ static int list_users(sd_bus *bus, char **args, unsigned n) {
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        printf("\n%u users listed.\n", k);
+        if (arg_legend)
+                printf("\n%u users listed.\n", k);
 
         return 0;
 }
@@ -180,7 +185,8 @@ static int list_seats(sd_bus *bus, char **args, unsigned n) {
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        printf("%-16s\n", "SEAT");
+        if (arg_legend)
+                printf("%-16s\n", "SEAT");
 
         while ((r = sd_bus_message_read(reply, "(so)", &seat, &object)) > 0) {
                 printf("%-16s\n", seat);
@@ -189,7 +195,8 @@ static int list_seats(sd_bus *bus, char **args, unsigned n) {
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        printf("\n%u seats listed.\n", k);
+        if (arg_legend)
+                printf("\n%u seats listed.\n", k);
 
         return 0;
 }
@@ -346,7 +353,7 @@ static int prop_map_sessions_strv(sd_bus *bus, const char *member, sd_bus_messag
         return sd_bus_message_exit_container(m);
 }
 
-static int print_session_status_info(sd_bus *bus, const char *path) {
+static int print_session_status_info(sd_bus *bus, const char *path, bool *new_line) {
 
         static const struct bus_properties_map map[]  = {
                 { "Id",         "s", NULL, offsetof(SessionStatusInfo, id) },
@@ -375,8 +382,15 @@ static int print_session_status_info(sd_bus *bus, const char *path) {
         int r;
 
         r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
-        if (r < 0)
+        if (r < 0) {
+                log_error("Could not get properties: %s", strerror(-r));
                 return r;
+        }
+
+        if (*new_line)
+                printf("\n");
+
+        *new_line = true;
 
         printf("%s - ", strna(i.id));
 
@@ -457,7 +471,7 @@ static int print_session_status_info(sd_bus *bus, const char *path) {
         return 0;
 }
 
-static int print_user_status_info(sd_bus *bus, const char *path) {
+static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line) {
 
         static const struct bus_properties_map map[]  = {
                 { "Name",       "s",     NULL, offsetof(UserStatusInfo, name) },
@@ -476,8 +490,15 @@ static int print_user_status_info(sd_bus *bus, const char *path) {
         int r;
 
         r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
-        if (r < 0)
+        if (r < 0) {
+                log_error("Could not get properties: %s", strerror(-r));
                 goto finish;
+        }
+
+        if (*new_line)
+                printf("\n");
+
+        *new_line = true;
 
         if (i.name)
                 printf("%s (%u)\n", i.name, (unsigned) i.uid);
@@ -517,10 +538,10 @@ static int print_user_status_info(sd_bus *bus, const char *path) {
 finish:
         strv_free(i.sessions);
 
-        return 0;
+        return r;
 }
 
-static int print_seat_status_info(sd_bus *bus, const char *path) {
+static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line) {
 
         static const struct bus_properties_map map[]  = {
                 { "Id",            "s",     NULL, offsetof(SeatStatusInfo, id) },
@@ -533,8 +554,15 @@ static int print_seat_status_info(sd_bus *bus, const char *path) {
         int r;
 
         r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
-        if (r < 0)
+        if (r < 0) {
+                log_error("Could not get properties: %s", strerror(-r));
                 goto finish;
+        }
+
+        if (*new_line)
+                printf("\n");
+
+        *new_line = true;
 
         printf("%s\n", strna(i.id));
 
@@ -569,29 +597,40 @@ static int print_seat_status_info(sd_bus *bus, const char *path) {
 finish:
         strv_free(i.sessions);
 
-        return 0;
+        return r;
+}
+
+static int show_properties(sd_bus *bus, const char *path, bool *new_line) {
+        int r;
+
+        if (*new_line)
+                printf("\n");
+
+        *new_line = true;
+
+        r = bus_print_all_properties(bus, "org.freedesktop.login1", path, arg_property, arg_all);
+        if (r < 0)
+                log_error("Could not get properties: %s", strerror(-r));
+
+        return r;
 }
 
 static int show_session(sd_bus *bus, char **args, unsigned n) {
-        bool show_properties;
+        bool properties, new_line = false;
         unsigned i;
         int r;
 
         assert(bus);
         assert(args);
 
-        show_properties = !strstr(args[0], "status");
+        properties = !strstr(args[0], "status");
 
         pager_open_if_enabled();
 
-        if (show_properties && n <= 1) {
+        if (properties && n <= 1) {
                 /* If not argument is specified inspect the manager
                  * itself */
-                r = bus_print_all_properties(bus, "org.freedesktop.login1", "/org/freedesktop/login1", NULL, arg_all);
-                if (r < 0)
-                        log_error("Failed to query login manager.");
-
-                return r;
+                return show_properties(bus, "/org/freedesktop/login1", &new_line);
         }
 
         for (i = 1; i < n; i++) {
@@ -599,9 +638,6 @@ static int show_session(sd_bus *bus, char **args, unsigned n) {
                 _cleanup_bus_message_unref_ sd_bus_message * reply = NULL;
                 const char *path = NULL;
 
-                if (i != 1)
-                        printf("\n");
-
                 r = sd_bus_call_method(
                                 bus,
                                 "org.freedesktop.login1",
@@ -619,39 +655,34 @@ static int show_session(sd_bus *bus, char **args, unsigned n) {
                 if (r < 0)
                         return bus_log_parse_error(r);
 
-                if (show_properties)
-                        r = bus_print_all_properties(bus, "org.freedesktop.login1", path, NULL, arg_all);
+                if (properties)
+                        r = show_properties(bus, path, &new_line);
                 else
-                        r = print_session_status_info(bus, path);
-                if (r < 0) {
-                        log_error("Failed to query session: %s", strerror(-r));
+                        r = print_session_status_info(bus, path, &new_line);
+
+                if (r < 0)
                         return r;
-                }
         }
 
         return 0;
 }
 
 static int show_user(sd_bus *bus, char **args, unsigned n) {
-        bool show_properties;
+        bool properties, new_line = false;
         unsigned i;
         int r;
 
         assert(bus);
         assert(args);
 
-        show_properties = !strstr(args[0], "status");
+        properties = !strstr(args[0], "status");
 
         pager_open_if_enabled();
 
-        if (show_properties && n <= 1) {
+        if (properties && n <= 1) {
                 /* If not argument is specified inspect the manager
                  * itself */
-                r = bus_print_all_properties(bus, "org.freedesktop.login1", "/org/freedesktop/login1", NULL, arg_all);
-                if (r < 0)
-                        log_error("Failed to query login manager.");
-
-                return r;
+                return show_properties(bus, "/org/freedesktop/login1", &new_line);
         }
 
         for (i = 1; i < n; i++) {
@@ -660,9 +691,6 @@ static int show_user(sd_bus *bus, char **args, unsigned n) {
                 const char *path = NULL;
                 uid_t uid;
 
-                if (i != 1)
-                        printf("\n");
-
                 r = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL);
                 if (r < 0) {
                         log_error("Failed to look up user %s: %s", args[i], strerror(-r));
@@ -686,39 +714,34 @@ static int show_user(sd_bus *bus, char **args, unsigned n) {
                 if (r < 0)
                         return bus_log_parse_error(r);
 
-                if (show_properties)
-                        r = bus_print_all_properties(bus, "org.freedesktop.login1", path, NULL, arg_all);
+                if (properties)
+                        r = show_properties(bus, path, &new_line);
                 else
-                        r = print_user_status_info(bus, path);
-                if (r < 0) {
-                        log_error("Failed to query user: %s", strerror(-r));
+                        r = print_user_status_info(bus, path, &new_line);
+
+                if (r < 0)
                         return r;
-                }
         }
 
         return 0;
 }
 
 static int show_seat(sd_bus *bus, char **args, unsigned n) {
-        bool show_properties;
+        bool properties, new_line = false;
         unsigned i;
         int r;
 
         assert(bus);
         assert(args);
 
-        show_properties = !strstr(args[0], "status");
+        properties = !strstr(args[0], "status");
 
         pager_open_if_enabled();
 
-        if (show_properties && n <= 1) {
+        if (properties && n <= 1) {
                 /* If not argument is specified inspect the manager
                  * itself */
-                r = bus_print_all_properties(bus, "org.freedesktop.login1", "/org/freedesktop/login1", NULL, arg_all);
-                if (r < 0)
-                        log_error("Failed to query login manager.");
-
-                return r;
+                return show_properties(bus, "/org/freedesktop/login1", &new_line);
         }
 
         for (i = 1; i < n; i++) {
@@ -726,9 +749,6 @@ static int show_seat(sd_bus *bus, char **args, unsigned n) {
                 _cleanup_bus_message_unref_ sd_bus_message * reply = NULL;
                 const char *path = NULL;
 
-                if (i != 1)
-                        printf("\n");
-
                 r = sd_bus_call_method(
                                 bus,
                                 "org.freedesktop.login1",
@@ -746,14 +766,13 @@ static int show_seat(sd_bus *bus, char **args, unsigned n) {
                 if (r < 0)
                         return bus_log_parse_error(r);
 
-                if (show_properties)
-                        r = bus_print_all_properties(bus, "org.freedesktop.login1", path, NULL, arg_all);
+                if (properties)
+                        r = show_properties(bus, path, &new_line);
                 else
-                        r = print_seat_status_info(bus, path);
-                if (r < 0) {
-                        log_error("Failed to query seat: %s", strerror(-r));
+                        r = print_seat_status_info(bus, path, &new_line);
+
+                if (r < 0)
                         return r;
-                }
         }
 
         return 0;
@@ -1028,6 +1047,7 @@ static int help(void) {
                "  -h --help              Show this help\n"
                "     --version           Show package version\n"
                "     --no-pager          Do not pipe output into a pager\n"
+               "     --no-legend         Do not show the headers and footers\n"
                "     --no-ask-password   Don't prompt for password\n"
                "  -H --host=[USER@]HOST  Operate on remote host\n"
                "  -M --machine=CONTAINER Operate on local container\n"
@@ -1070,6 +1090,7 @@ static int parse_argv(int argc, char *argv[]) {
         enum {
                 ARG_VERSION = 0x100,
                 ARG_NO_PAGER,
+                ARG_NO_LEGEND,
                 ARG_KILL_WHO,
                 ARG_NO_ASK_PASSWORD,
         };
@@ -1081,6 +1102,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "all",             no_argument,       NULL, 'a'                 },
                 { "full",            no_argument,       NULL, 'l'                 },
                 { "no-pager",        no_argument,       NULL, ARG_NO_PAGER        },
+                { "no-legend",       no_argument,       NULL, ARG_NO_LEGEND       },
                 { "kill-who",        required_argument, NULL, ARG_KILL_WHO        },
                 { "signal",          required_argument, NULL, 's'                 },
                 { "host",            required_argument, NULL, 'H'                 },
@@ -1089,7 +1111,7 @@ static int parse_argv(int argc, char *argv[]) {
                 {}
         };
 
-        int c;
+        int c, r;
 
         assert(argc >= 0);
         assert(argv);
@@ -1107,14 +1129,9 @@ static int parse_argv(int argc, char *argv[]) {
                         return 0;
 
                 case 'p': {
-                        char **l;
-
-                        l = strv_append(arg_property, optarg);
-                        if (!l)
-                                return -ENOMEM;
-
-                        strv_free(arg_property);
-                        arg_property = l;
+                        r = strv_extend(&arg_property, optarg);
+                        if (r < 0)
+                                return log_oom();
 
                         /* If the user asked for a particular
                          * property, show it to him, even if it is
@@ -1135,6 +1152,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_no_pager = true;
                         break;
 
+                case ARG_NO_LEGEND:
+                        arg_legend = false;
+                        break;
+
                 case ARG_NO_ASK_PASSWORD:
                         arg_ask_password = false;
                         break;