mirror of
https://github.com/systemd/systemd.git
synced 2025-03-08 08:58:27 +03:00
Merge pull request #27769 from YHNdnzj/loginctl-followup
loginctl: some follow-ups
This commit is contained in:
commit
9e7b922c8f
@ -58,7 +58,7 @@ typedef struct SessionStatusInfo {
|
||||
const char *id;
|
||||
uid_t uid;
|
||||
const char *name;
|
||||
struct dual_timestamp timestamp;
|
||||
dual_timestamp timestamp;
|
||||
unsigned vtnr;
|
||||
const char *seat;
|
||||
const char *tty;
|
||||
@ -74,11 +74,39 @@ typedef struct SessionStatusInfo {
|
||||
const char *scope;
|
||||
const char *desktop;
|
||||
bool idle_hint;
|
||||
dual_timestamp idle_hint_timestamp;
|
||||
usec_t idle_hint_timestamp;
|
||||
} SessionStatusInfo;
|
||||
|
||||
static OutputFlags get_output_flags(void) {
|
||||
typedef struct UserStatusInfo {
|
||||
uid_t uid;
|
||||
bool linger;
|
||||
const char *name;
|
||||
dual_timestamp timestamp;
|
||||
const char *state;
|
||||
char **sessions;
|
||||
const char *display;
|
||||
const char *slice;
|
||||
} UserStatusInfo;
|
||||
|
||||
typedef struct SeatStatusInfo {
|
||||
const char *id;
|
||||
const char *active_session;
|
||||
char **sessions;
|
||||
} SeatStatusInfo;
|
||||
|
||||
static void user_status_info_done(UserStatusInfo *info) {
|
||||
assert(info);
|
||||
|
||||
strv_free(info->sessions);
|
||||
}
|
||||
|
||||
static void seat_status_info_done(SeatStatusInfo *info) {
|
||||
assert(info);
|
||||
|
||||
strv_free(info->sessions);
|
||||
}
|
||||
|
||||
static OutputFlags get_output_flags(void) {
|
||||
return
|
||||
FLAGS_SET(arg_print_flags, BUS_PRINT_PROPERTY_SHOW_EMPTY) * OUTPUT_SHOW_ALL |
|
||||
(arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
|
||||
@ -87,8 +115,13 @@ static OutputFlags get_output_flags(void) {
|
||||
|
||||
static int get_session_path(sd_bus *bus, const char *session_id, sd_bus_error *error, char **path) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
int r;
|
||||
char *ans;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(session_id);
|
||||
assert(error);
|
||||
assert(path);
|
||||
|
||||
r = bus_call_method(bus, bus_login_mgr, "GetSession", error, &reply, "s", session_id);
|
||||
if (r < 0)
|
||||
@ -139,11 +172,11 @@ static int show_table(Table *table, const char *word) {
|
||||
|
||||
static int list_sessions(int argc, char *argv[], void *userdata) {
|
||||
|
||||
static const struct bus_properties_map map[] = {
|
||||
{ "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) },
|
||||
{ "IdleSinceHintMonotonic", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic) },
|
||||
{ "State", "s", NULL, offsetof(SessionStatusInfo, state) },
|
||||
{ "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
|
||||
static const struct bus_properties_map map[] = {
|
||||
{ "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) },
|
||||
{ "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) },
|
||||
{ "State", "s", NULL, offsetof(SessionStatusInfo, state) },
|
||||
{ "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
|
||||
{},
|
||||
};
|
||||
|
||||
@ -207,7 +240,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
|
||||
return table_log_add_error(r);
|
||||
|
||||
if (i.idle_hint)
|
||||
r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic);
|
||||
r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp);
|
||||
else
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
@ -222,6 +255,13 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
|
||||
}
|
||||
|
||||
static int list_users(int argc, char *argv[], void *userdata) {
|
||||
|
||||
static const struct bus_properties_map property_map[] = {
|
||||
{ "Linger", "b", NULL, offsetof(UserStatusInfo, linger) },
|
||||
{ "State", "s", NULL, offsetof(UserStatusInfo, state) },
|
||||
{},
|
||||
};
|
||||
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
@ -248,10 +288,10 @@ static int list_users(int argc, char *argv[], void *userdata) {
|
||||
|
||||
for (;;) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error_property = SD_BUS_ERROR_NULL;
|
||||
_cleanup_free_ char *state = NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_property = NULL;
|
||||
_cleanup_(user_status_info_done) UserStatusInfo info = {};
|
||||
const char *user, *object;
|
||||
uint32_t uid;
|
||||
int linger;
|
||||
|
||||
r = sd_bus_message_read(reply, "(uso)", &uid, &user, &object);
|
||||
if (r < 0)
|
||||
@ -259,44 +299,27 @@ static int list_users(int argc, char *argv[], void *userdata) {
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = sd_bus_get_property_trivial(bus,
|
||||
"org.freedesktop.login1",
|
||||
object,
|
||||
"org.freedesktop.login1.User",
|
||||
"Linger",
|
||||
&error_property,
|
||||
'b',
|
||||
&linger);
|
||||
r = bus_map_all_properties(bus,
|
||||
"org.freedesktop.login1",
|
||||
object,
|
||||
property_map,
|
||||
BUS_MAP_BOOLEAN_AS_BOOL,
|
||||
&error_property,
|
||||
&reply_property,
|
||||
&info);
|
||||
if (r < 0) {
|
||||
if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
|
||||
/* The user logged out when we're querying the property */
|
||||
continue;
|
||||
|
||||
return log_error_errno(r, "Failed to get linger status for user %s: %s",
|
||||
user, bus_error_message(&error_property, r));
|
||||
}
|
||||
|
||||
r = sd_bus_get_property_string(bus,
|
||||
"org.freedesktop.login1",
|
||||
object,
|
||||
"org.freedesktop.login1.User",
|
||||
"State",
|
||||
&error_property,
|
||||
&state);
|
||||
if (r < 0) {
|
||||
if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
|
||||
/* The user logged out when we're querying the property */
|
||||
continue;
|
||||
|
||||
return log_error_errno(r, "Failed to get state for user %s: %s",
|
||||
user, bus_error_message(&error_property, r));
|
||||
log_full_errno(sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT) ? LOG_DEBUG : LOG_WARNING,
|
||||
r,
|
||||
"Failed to get properties of user %s, ignoring: %s",
|
||||
user, bus_error_message(&error_property, r));
|
||||
continue;
|
||||
}
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_UID, (uid_t) uid,
|
||||
TABLE_STRING, user,
|
||||
TABLE_BOOLEAN, linger,
|
||||
TABLE_STRING, state);
|
||||
TABLE_BOOLEAN, info.linger,
|
||||
TABLE_STRING, info.state);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
@ -392,41 +415,13 @@ static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct UserStatusInfo {
|
||||
uid_t uid;
|
||||
bool linger;
|
||||
const char *name;
|
||||
struct dual_timestamp timestamp;
|
||||
const char *state;
|
||||
char **sessions;
|
||||
const char *display;
|
||||
const char *slice;
|
||||
} UserStatusInfo;
|
||||
|
||||
typedef struct SeatStatusInfo {
|
||||
const char *id;
|
||||
const char *active_session;
|
||||
char **sessions;
|
||||
} SeatStatusInfo;
|
||||
|
||||
static void user_status_info_clear(UserStatusInfo *info) {
|
||||
if (info) {
|
||||
strv_free(info->sessions);
|
||||
zero(*info);
|
||||
}
|
||||
}
|
||||
|
||||
static void seat_status_info_clear(SeatStatusInfo *info) {
|
||||
if (info) {
|
||||
strv_free(info->sessions);
|
||||
zero(*info);
|
||||
}
|
||||
}
|
||||
|
||||
static int prop_map_first_of_struct(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
const char *contents;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(m);
|
||||
|
||||
r = sd_bus_message_peek_type(m, NULL, &contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -474,26 +469,28 @@ static int prop_map_sessions_strv(sd_bus *bus, const char *member, sd_bus_messag
|
||||
|
||||
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) },
|
||||
{ "Name", "s", NULL, offsetof(SessionStatusInfo, name) },
|
||||
{ "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
|
||||
{ "Display", "s", NULL, offsetof(SessionStatusInfo, display) },
|
||||
{ "RemoteHost", "s", NULL, offsetof(SessionStatusInfo, remote_host) },
|
||||
{ "RemoteUser", "s", NULL, offsetof(SessionStatusInfo, remote_user) },
|
||||
{ "Service", "s", NULL, offsetof(SessionStatusInfo, service) },
|
||||
{ "Desktop", "s", NULL, offsetof(SessionStatusInfo, desktop) },
|
||||
{ "Type", "s", NULL, offsetof(SessionStatusInfo, type) },
|
||||
{ "Class", "s", NULL, offsetof(SessionStatusInfo, class) },
|
||||
{ "Scope", "s", NULL, offsetof(SessionStatusInfo, scope) },
|
||||
{ "State", "s", NULL, offsetof(SessionStatusInfo, state) },
|
||||
{ "VTNr", "u", NULL, offsetof(SessionStatusInfo, vtnr) },
|
||||
{ "Leader", "u", NULL, offsetof(SessionStatusInfo, leader) },
|
||||
{ "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) },
|
||||
{ "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) },
|
||||
{ "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) },
|
||||
{ "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) },
|
||||
{ "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) },
|
||||
static const struct bus_properties_map map[] = {
|
||||
{ "Id", "s", NULL, offsetof(SessionStatusInfo, id) },
|
||||
{ "Name", "s", NULL, offsetof(SessionStatusInfo, name) },
|
||||
{ "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
|
||||
{ "Display", "s", NULL, offsetof(SessionStatusInfo, display) },
|
||||
{ "RemoteHost", "s", NULL, offsetof(SessionStatusInfo, remote_host) },
|
||||
{ "RemoteUser", "s", NULL, offsetof(SessionStatusInfo, remote_user) },
|
||||
{ "Service", "s", NULL, offsetof(SessionStatusInfo, service) },
|
||||
{ "Desktop", "s", NULL, offsetof(SessionStatusInfo, desktop) },
|
||||
{ "Type", "s", NULL, offsetof(SessionStatusInfo, type) },
|
||||
{ "Class", "s", NULL, offsetof(SessionStatusInfo, class) },
|
||||
{ "Scope", "s", NULL, offsetof(SessionStatusInfo, scope) },
|
||||
{ "State", "s", NULL, offsetof(SessionStatusInfo, state) },
|
||||
{ "VTNr", "u", NULL, offsetof(SessionStatusInfo, vtnr) },
|
||||
{ "Leader", "u", NULL, offsetof(SessionStatusInfo, leader) },
|
||||
{ "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) },
|
||||
{ "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) },
|
||||
{ "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) },
|
||||
{ "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) },
|
||||
{ "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) },
|
||||
{ "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) },
|
||||
{ "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -584,6 +581,14 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li
|
||||
if (i.state)
|
||||
printf("\t State: %s\n", i.state);
|
||||
|
||||
if (i.idle_hint && timestamp_is_set(i.idle_hint_timestamp))
|
||||
printf("\t Idle: %s since %s (%s)\n",
|
||||
yes_no(i.idle_hint),
|
||||
FORMAT_TIMESTAMP(i.idle_hint_timestamp),
|
||||
FORMAT_TIMESTAMP_RELATIVE(i.idle_hint_timestamp));
|
||||
else
|
||||
printf("\t Idle: %s\n", yes_no(i.idle_hint));
|
||||
|
||||
if (i.scope) {
|
||||
printf("\t Unit: %s\n", i.scope);
|
||||
show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i.scope, i.leader);
|
||||
@ -609,7 +614,7 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li
|
||||
|
||||
static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line) {
|
||||
|
||||
static const struct bus_properties_map map[] = {
|
||||
static const struct bus_properties_map map[] = {
|
||||
{ "Name", "s", NULL, offsetof(UserStatusInfo, name) },
|
||||
{ "Linger", "b", NULL, offsetof(UserStatusInfo, linger) },
|
||||
{ "Slice", "s", NULL, offsetof(UserStatusInfo, slice) },
|
||||
@ -624,7 +629,7 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
|
||||
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||
_cleanup_(user_status_info_clear) UserStatusInfo i = {};
|
||||
_cleanup_(user_status_info_done) UserStatusInfo i = {};
|
||||
int r;
|
||||
|
||||
r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, BUS_MAP_BOOLEAN_AS_BOOL, &error, &m, &i);
|
||||
@ -686,7 +691,7 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
|
||||
|
||||
static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line) {
|
||||
|
||||
static const struct bus_properties_map map[] = {
|
||||
static const struct bus_properties_map map[] = {
|
||||
{ "Id", "s", NULL, offsetof(SeatStatusInfo, id) },
|
||||
{ "ActiveSession", "(so)", prop_map_first_of_struct, offsetof(SeatStatusInfo, active_session) },
|
||||
{ "Sessions", "a(so)", prop_map_sessions_strv, offsetof(SeatStatusInfo, sessions) },
|
||||
@ -695,7 +700,7 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line)
|
||||
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||
_cleanup_(seat_status_info_clear) SeatStatusInfo i = {};
|
||||
_cleanup_(seat_status_info_done) SeatStatusInfo i = {};
|
||||
int r;
|
||||
|
||||
r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, 0, &error, &m, &i);
|
||||
@ -1003,7 +1008,6 @@ static int activate(int argc, char *argv[], void *userdata) {
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
||||
r = bus_call_method(
|
||||
bus,
|
||||
bus_login_mgr,
|
||||
@ -1033,7 +1037,6 @@ static int kill_session(int argc, char *argv[], void *userdata) {
|
||||
arg_kill_whom = "all";
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
||||
r = bus_call_method(
|
||||
bus,
|
||||
bus_login_mgr,
|
||||
|
Loading…
x
Reference in New Issue
Block a user