loginctl.c revision c529695e7a30b300fdaa61ace4a8a4ed0e94ad1c
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering This file is part of systemd.
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Copyright 2010 Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering systemd is free software; you can redistribute it and/or modify it
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering under the terms of the GNU Lesser General Public License as published by
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering (at your option) any later version.
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering systemd is distributed in the hope that it will be useful, but
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Lesser General Public License for more details.
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering You should have received a copy of the GNU Lesser General Public License
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic bool arg_all = false;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic bool arg_full = false;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poetteringstatic bool arg_no_pager = false;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poetteringstatic bool arg_legend = true;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poetteringstatic bool arg_ask_password = true;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poetteringstatic OutputMode arg_output = OUTPUT_SHORT;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poetteringstatic void pager_open_if_enabled(void) {
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poetteringstatic void polkit_agent_open_if_enabled(void) {
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering /* Open the polkit agent as a child process if necessary */
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL)
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poetteringstatic OutputFlags get_output_flags(void) {
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poetteringstatic int list_sessions(int argc, char *argv[], void *userdata) {
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering unsigned k = 0;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering "org.freedesktop.login1",
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering "org.freedesktop.login1.Manager",
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering "ListSessions",
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering log_error("Failed to list sessions: %s", bus_error_message(&error, r));
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(susso)");
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering printf("%10s %10s %-16s %-16s\n", "SESSION", "UID", "USER", "SEAT");
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering while ((r = sd_bus_message_read(reply, "(susso)", &id, &uid, &user, &seat, &object)) > 0) {
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering printf("%10s %10u %-16s %-16s\n", id, (unsigned) uid, user, seat);
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int list_users(int argc, char *argv[], void *userdata) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering unsigned k = 0;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering "org.freedesktop.login1",
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering "org.freedesktop.login1.Manager",
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering log_error("Failed to list users: %s", bus_error_message(&error, r));
7de80bfe2e61d5818601ccfddbadad3b7703ed70Karel Zak r = sd_bus_message_enter_container(reply, 'a', "(uso)");
3ef63c317481c2b3f1fe39e1b0f130aac3544522Lennart Poettering while ((r = sd_bus_message_read(reply, "(uso)", &uid, &user, &object)) > 0) {
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering printf("%10u %-16s\n", (unsigned) uid, user);
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poetteringstatic int list_seats(int argc, char *argv[], void *userdata) {
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering unsigned k = 0;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering "org.freedesktop.login1",
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering "org.freedesktop.login1.Manager",
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering log_error("Failed to list seats: %s", bus_error_message(&error, r));
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(so)");
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering while ((r = sd_bus_message_read(reply, "(so)", &seat, &object)) > 0) {
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poetteringstatic int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit, pid_t leader) {
3ef63c317481c2b3f1fe39e1b0f130aac3544522Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL)
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering "ControlGroup",
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering r = sd_bus_message_read(reply, "s", &cgroup);
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, get_output_flags());
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int prop_map_first_of_struct(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering r = sd_bus_message_peek_type(m, NULL, &contents);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, contents);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering if (contents[0] == 's' || contents[0] == 'o') {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering const char *s;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering char **p = (char **) userdata;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering r = sd_bus_message_read_basic(m, contents[0], &s);
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering r = sd_bus_message_read_basic(m, contents[0], userdata);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poetteringstatic int prop_map_sessions_strv(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering r = sd_bus_message_enter_container(m, 'a', "(so)");
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering while ((r = sd_bus_message_read(m, "(so)", &name, NULL)) > 0) {
067d851d30386c553e3a84f59d81d003ff638b91Daniel Wallacestatic int print_session_status_info(sd_bus *bus, const char *path, bool *new_line) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering static const struct bus_properties_map map[] = {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { "Id", "s", NULL, offsetof(SessionStatusInfo, id) },
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering { "Name", "s", NULL, offsetof(SessionStatusInfo, name) },
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering { "Display", "s", NULL, offsetof(SessionStatusInfo, display) },
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering { "RemoteHost", "s", NULL, offsetof(SessionStatusInfo, remote_host) },
6aaa8c2f783cd1b3ac27c5ce40625d032e7e3d71Zbigniew Jędrzejewski-Szmek { "RemoteUser", "s", NULL, offsetof(SessionStatusInfo, remote_user) },
6aaa8c2f783cd1b3ac27c5ce40625d032e7e3d71Zbigniew Jędrzejewski-Szmek { "Service", "s", NULL, offsetof(SessionStatusInfo, service) },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { "Desktop", "s", NULL, offsetof(SessionStatusInfo, desktop) },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { "Type", "s", NULL, offsetof(SessionStatusInfo, type) },
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering { "Class", "s", NULL, offsetof(SessionStatusInfo, class) },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { "Scope", "s", NULL, offsetof(SessionStatusInfo, scope) },
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { "VTNr", "u", NULL, offsetof(SessionStatusInfo, vtnr) },
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering { "Leader", "u", NULL, offsetof(SessionStatusInfo, leader) },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) },
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering { "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering return log_error_errno(r, "Could not get properties: %m");
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering printf("%s (%u)\n", i.name, (unsigned) i.uid);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering s1 = format_timestamp_relative(since1, sizeof(since1), i.timestamp.realtime);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering s2 = format_timestamp(since2, sizeof(since2), i.timestamp.realtime);
else if (s2)
if (i.leader > 0) {
if (i.vtnr > 0)
if (i.tty)
else if (i.display)
else if (i.remote_host)
else if (i.remote_user)
else if (i.remote)
if (i.service) {
if (i.type)
if (i.class)
} else if (i.type) {
if (i.class)
} else if (i.class)
if (i.state)
if (i.scope) {
i.scope,
NULL);
UserStatusInfo i = {};
goto finish;
if (*new_line)
*new_line = true;
if (i.name)
if (s1)
else if (s2)
if (i.slice) {
i.slice,
NULL);
SeatStatusInfo i = {};
goto finish;
if (*new_line)
*new_line = true;
c = columns();
if (*new_line)
*new_line = true;
if (properties)
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
return bus_log_parse_error(r);
if (properties)
if (properties)
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
return bus_log_parse_error(r);
if (properties)
if (properties)
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
return bus_log_parse_error(r);
if (properties)
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
if (!arg_kill_who)
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
if (!arg_kill_who)
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
NULL);
r = sd_bus_call_method(
bus,
"/org/freedesktop/login1",
case ARG_VERSION:
return log_oom();
arg_all = true;
arg_all = true;
arg_full = true;
return -EINVAL;
if (arg_output < 0) {
return -EINVAL;
case ARG_NO_PAGER:
arg_no_pager = true;
case ARG_NO_LEGEND:
arg_legend = false;
case ARG_NO_ASK_PASSWORD:
arg_ask_password = false;
case ARG_KILL_WHO:
if (arg_signal < 0) {
return -EINVAL;
return -EINVAL;
log_open();
goto finish;
goto finish;
pager_close();