1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-29 21:47:05 +03:00

loginctl: implement more verbs

This commit is contained in:
Lennart Poettering 2011-07-09 02:58:05 +02:00
parent d4b36d99f1
commit 88e3dc903b
5 changed files with 386 additions and 32 deletions

View File

@ -527,14 +527,13 @@ static void print_seat_status_info(SeatStatusInfo *i) {
unsigned c;
c = columns();
if (c > 18)
c -= 18;
if (c > 21)
c -= 21;
else
c = 0;
printf("\t Devices:\n");
show_sysfs(i->id, "\t\t ", c);
}
}
@ -1166,7 +1165,10 @@ static int activate(DBusConnection *bus, char **args, unsigned n) {
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"ActivateSession");
streq(args[0], "lock-session") ? "LockSession" :
streq(args[0], "unlock-session") ? "UnlockSession" :
streq(args[0], "terminate-session") ? "TerminateSession" :
"ActivateSession");
if (!m) {
log_error("Could not allocate message.");
ret = -ENOMEM;
@ -1210,19 +1212,312 @@ static int kill_session(DBusConnection *bus, char **args, unsigned n) {
}
static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
return 0;
DBusMessage *m = NULL, *reply = NULL;
int ret = 0;
DBusError error;
unsigned i;
dbus_bool_t b, interactive = true;
assert(bus);
assert(args);
dbus_error_init(&error);
b = streq(args[0], "enable-linger");
for (i = 1; i < n; i++) {
uint32_t uid;
m = dbus_message_new_method_call(
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"SetUserLinger");
if (!m) {
log_error("Could not allocate message.");
ret = -ENOMEM;
goto finish;
}
if (safe_atou32(args[i], &uid) < 0) {
struct passwd *pw;
errno = 0;
pw = getpwnam(args[i]);
if (!pw) {
ret = errno ? -errno : -ENOENT;
log_error("Failed to resolve user %s: %s", args[i], strerror(-ret));
goto finish;
}
uid = pw->pw_uid;
}
if (!dbus_message_append_args(m,
DBUS_TYPE_UINT32, &uid,
DBUS_TYPE_BOOLEAN, &b,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID)) {
log_error("Could not append arguments to message.");
ret = -ENOMEM;
goto finish;
}
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
if (!reply) {
log_error("Failed to issue method call: %s", bus_error_message(&error));
ret = -EIO;
goto finish;
}
dbus_message_unref(m);
dbus_message_unref(reply);
m = reply = NULL;
}
finish:
if (m)
dbus_message_unref(m);
if (reply)
dbus_message_unref(reply);
dbus_error_free(&error);
return ret;
}
static int terminate_user(DBusConnection *bus, char **args, unsigned n) {
DBusMessage *m = NULL, *reply = NULL;
int ret = 0;
DBusError error;
unsigned i;
assert(bus);
assert(args);
dbus_error_init(&error);
for (i = 1; i < n; i++) {
uint32_t u;
m = dbus_message_new_method_call(
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"TerminateUser");
if (!m) {
log_error("Could not allocate message.");
ret = -ENOMEM;
goto finish;
}
if (safe_atou32(args[i], &u) < 0) {
struct passwd *pw;
errno = 0;
pw = getpwnam(args[i]);
if (!pw) {
ret = errno ? -errno : -ENOENT;
log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
goto finish;
}
u = pw->pw_uid;
}
if (!dbus_message_append_args(m,
DBUS_TYPE_UINT32, &u,
DBUS_TYPE_INVALID)) {
log_error("Could not append arguments to message.");
ret = -ENOMEM;
goto finish;
}
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
if (!reply) {
log_error("Failed to issue method call: %s", bus_error_message(&error));
ret = -EIO;
goto finish;
}
dbus_message_unref(m);
dbus_message_unref(reply);
m = reply = NULL;
}
finish:
if (m)
dbus_message_unref(m);
if (reply)
dbus_message_unref(reply);
dbus_error_free(&error);
return ret;
}
static int attach(DBusConnection *bus, char **args, unsigned n) {
return 0;
DBusMessage *m = NULL, *reply = NULL;
int ret = 0;
DBusError error;
unsigned i;
dbus_bool_t interactive = true;
assert(bus);
assert(args);
dbus_error_init(&error);
for (i = 2; i < n; i++) {
m = dbus_message_new_method_call(
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"AttachDevice");
if (!m) {
log_error("Could not allocate message.");
ret = -ENOMEM;
goto finish;
}
if (!dbus_message_append_args(m,
DBUS_TYPE_STRING, &args[1],
DBUS_TYPE_STRING, &args[i],
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID)) {
log_error("Could not append arguments to message.");
ret = -ENOMEM;
goto finish;
}
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
if (!reply) {
log_error("Failed to issue method call: %s", bus_error_message(&error));
ret = -EIO;
goto finish;
}
dbus_message_unref(m);
dbus_message_unref(reply);
m = reply = NULL;
}
finish:
if (m)
dbus_message_unref(m);
if (reply)
dbus_message_unref(reply);
dbus_error_free(&error);
return ret;
}
static int flush_devices(DBusConnection *bus, char **args, unsigned n) {
return 0;
DBusMessage *m = NULL, *reply = NULL;
int ret = 0;
DBusError error;
dbus_bool_t interactive = true;
assert(bus);
assert(args);
dbus_error_init(&error);
m = dbus_message_new_method_call(
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"FlushDevices");
if (!m) {
log_error("Could not allocate message.");
ret = -ENOMEM;
goto finish;
}
if (!dbus_message_append_args(m,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID)) {
log_error("Could not append arguments to message.");
ret = -ENOMEM;
goto finish;
}
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
if (!reply) {
log_error("Failed to issue method call: %s", bus_error_message(&error));
ret = -EIO;
goto finish;
}
finish:
if (m)
dbus_message_unref(m);
if (reply)
dbus_message_unref(reply);
dbus_error_free(&error);
return ret;
}
static int terminate_seat(DBusConnection *bus, char **args, unsigned n) {
return 0;
DBusMessage *m = NULL, *reply = NULL;
int ret = 0;
DBusError error;
unsigned i;
assert(bus);
assert(args);
dbus_error_init(&error);
for (i = 1; i < n; i++) {
m = dbus_message_new_method_call(
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"TerminateSeat");
if (!m) {
log_error("Could not allocate message.");
ret = -ENOMEM;
goto finish;
}
if (!dbus_message_append_args(m,
DBUS_TYPE_STRING, &args[i],
DBUS_TYPE_INVALID)) {
log_error("Could not append arguments to message.");
ret = -ENOMEM;
goto finish;
}
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
if (!reply) {
log_error("Failed to issue method call: %s", bus_error_message(&error));
ret = -EIO;
goto finish;
}
dbus_message_unref(m);
dbus_message_unref(reply);
m = reply = NULL;
}
finish:
if (m)
dbus_message_unref(m);
if (reply)
dbus_message_unref(reply);
dbus_error_free(&error);
return ret;
}
static int help(void) {
@ -1245,6 +1540,7 @@ static int help(void) {
" show-session [ID...] Show property of one or more sessions\n"
" activate [ID] Activate a session\n"
" lock-session [ID...] Screen lock one or more sessions\n"
" unlock-session [ID...] Screen unlock one or more sessions\n"
" terminate-session [ID...] Terminate one or more sessions\n"
" kill-session [ID...] Send signal to processes of a session\n"
" list-users List users\n"
@ -1381,22 +1677,23 @@ static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
{ "show-session", MORE, 1, show },
{ "activate", EQUAL, 2, activate },
{ "lock-session", MORE, 2, activate },
{ "unlock-session", MORE, 2, activate },
{ "terminate-session", MORE, 2, activate },
{ "kill-session", MORE, 2, kill_session },
{ "kill-session", MORE, 2, kill_session }, /* missing */
{ "list-users", EQUAL, 1, list_users },
{ "user-status", MORE, 2, show },
{ "show-user", MORE, 1, show },
{ "enable-linger", MORE, 2, enable_linger },
{ "disable-linger", MORE, 2, enable_linger },
{ "terminate-user", MORE, 2, enable_linger },
{ "kill-user", MORE, 2, kill_session },
{ "terminate-user", MORE, 2, terminate_user },
{ "kill-user", MORE, 2, kill_session }, /* missing */
{ "list-seats", EQUAL, 1, list_seats },
{ "seat-status", MORE, 2, show },
{ "show-seat", MORE, 1, show },
{ "attach", MORE, 3, attach },
{ "flush-devices", EQUAL, 1, flush_devices },
{ "terminate-seat", MORE, 2, terminate_seat },
{ "kill-seat", MORE, 2, kill_session },
{ "terminate-seat", MORE, 2, terminate_seat }, /* missing */
{ "kill-seat", MORE, 2, kill_session }, /* missing */
};
int left;

View File

@ -75,6 +75,12 @@
" <method name=\"ActivateSession\">\n" \
" <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
" </method>\n" \
" <method name=\"LockSession\">\n" \
" <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
" </method>\n" \
" <method name=\"UnlockSession\">\n" \
" <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
" </method>\n" \
" <method name=\"TerminateSession\">\n" \
" <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
" </method>\n" \
@ -980,6 +986,29 @@ static DBusHandlerResult manager_message_handler(
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "LockSession") ||
dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "UnlockSession")) {
const char *name;
Session *session;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
session = hashmap_get(m->sessions, name);
if (!session)
return bus_send_error_reply(connection, message, &error, -ENOENT);
if (session_send_lock(session, streq(dbus_message_get_member(message), "LockSession")) < 0)
goto oom;
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSession")) {
const char *name;
Session *session;

View File

@ -283,17 +283,8 @@ static DBusHandlerResult session_message_dispatch(
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Lock") ||
dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Unlock")) {
bool b;
DBusMessage *sig;
sig = dbus_message_new_signal(dbus_message_get_path(message), "org.freedesktop.login1.Session", dbus_message_get_member(message));
if (!sig)
goto oom;
b = dbus_connection_send(connection, sig, NULL);
dbus_message_unref(sig);
if (!b)
if (session_send_signal(s, streq(dbus_message_get_member(message), "Lock")) < 0)
goto oom;
reply = dbus_message_new_method_return(message);
@ -460,3 +451,29 @@ finish:
return r;
}
int session_send_lock(Session *s, bool lock) {
DBusMessage *m;
bool b;
char *p;
assert(s);
p = session_bus_path(s);
if (!p)
return -ENOMEM;
m = dbus_message_new_signal(p, "org.freedesktop.login1.Session", lock ? "Lock" : "Unlock");
free(p);
if (!m)
return -ENOMEM;
b = dbus_connection_send(s->manager->bus, m, NULL);
dbus_message_unref(m);
if (!b)
return -ENOMEM;
return 0;
}

View File

@ -105,6 +105,7 @@ extern const DBusObjectPathVTable bus_session_vtable;
int session_send_signal(Session *s, bool new_session);
int session_send_changed(Session *s, const char *properties);
int session_send_lock(Session *s, bool lock);
const char* session_type_to_string(SessionType t);
SessionType session_type_from_string(const char *s);

View File

@ -59,7 +59,8 @@ static int show_sysfs_one(
while (*item) {
struct udev_list_entry *next, *lookahead;
struct udev_device *d;
const char *sn, *id, *name, *sysfs, *subsystem, *sysname;
const char *sn, *name, *sysfs, *subsystem, *sysname;
char *l, *k;
sysfs = udev_list_entry_get_name(*item);
if (!path_startswith(sysfs, sub))
@ -82,7 +83,6 @@ static int show_sysfs_one(
continue;
}
id = udev_device_get_property_value(d, "ID_FOR_SEAT");
name = udev_device_get_sysattr_value(d, "name");
if (!name)
name = udev_device_get_sysattr_value(d, "id");
@ -109,7 +109,7 @@ static int show_sysfs_one(
if (isempty(lookahead_sn))
lookahead_sn = "seat0";
found = streq(seat, lookahead_sn) && device_has_tag(d, "seat");
found = streq(seat, lookahead_sn) && device_has_tag(lookahead_d, "seat");
udev_device_unref(lookahead_d);
if (found)
@ -120,19 +120,29 @@ static int show_sysfs_one(
lookahead = udev_list_entry_get_next(lookahead);
}
printf("%s%s %s (%s:%s)", prefix, lookahead ? "\342\224\234" : "\342\224\224", id ? id : sysfs, subsystem, sysname);
k = ellipsize(sysfs, n_columns, 20);
printf("%s%s %s\n", prefix, lookahead ? "\342\224\234" : "\342\224\224", k ? k : sysfs);
free(k);
if (name)
printf(" \"%s\"\n", name);
else
printf("\n");
if (asprintf(&l,
"(%s:%s)%s%s%s",
subsystem, sysname,
name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0) {
udev_device_unref(d);
return -ENOMEM;
}
k = ellipsize(l, n_columns, 70);
printf("%s%s %s\n", prefix, lookahead ? "\342\224\202" : " ", k ? k : l);
free(k);
free(l);
*item = next;
if (*item) {
char *p;
p = strappend(prefix, lookahead ? "\342\224\202 " : " ");
show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2);
free(p);
}