mirror of
https://github.com/fairyglade/ly.git
synced 2025-12-20 19:24:53 +00:00
Remember last session for each user (closes #619)
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
134
src/main.zig
134
src/main.zig
@@ -21,7 +21,8 @@ const InfoLine = @import("tui/components/InfoLine.zig");
|
||||
const UserList = @import("tui/components/UserList.zig");
|
||||
const Config = @import("config/Config.zig");
|
||||
const Lang = @import("config/Lang.zig");
|
||||
const Save = @import("config/Save.zig");
|
||||
const OldSave = @import("config/OldSave.zig");
|
||||
const SavedUsers = @import("config/SavedUsers.zig");
|
||||
const migrator = @import("config/migrator.zig");
|
||||
const SharedError = @import("SharedError.zig");
|
||||
const UidRange = @import("UidRange.zig");
|
||||
@@ -118,11 +119,14 @@ pub fn main() !void {
|
||||
|
||||
var config: Config = undefined;
|
||||
var lang: Lang = undefined;
|
||||
var save: Save = undefined;
|
||||
var old_save_file_exists = false;
|
||||
var maybe_config_load_error: ?anyerror = null;
|
||||
var can_get_lock_state = true;
|
||||
var can_draw_clock = true;
|
||||
|
||||
var saved_users = SavedUsers.init();
|
||||
defer saved_users.deinit(allocator);
|
||||
|
||||
if (res.args.help != 0) {
|
||||
try clap.help(stderr, clap.Help, ¶ms, .{});
|
||||
|
||||
@@ -143,13 +147,15 @@ pub fn main() !void {
|
||||
var lang_ini = Ini(Lang).init(allocator);
|
||||
defer lang_ini.deinit();
|
||||
|
||||
var save_ini = Ini(Save).init(allocator);
|
||||
defer save_ini.deinit();
|
||||
var old_save_ini = ini.Ini(OldSave).init(allocator);
|
||||
defer old_save_ini.deinit();
|
||||
|
||||
var save_path: []const u8 = build_options.config_directory ++ "/ly/save.ini";
|
||||
var save_path: []const u8 = build_options.config_directory ++ "/ly/save.txt";
|
||||
var old_save_path: []const u8 = build_options.config_directory ++ "/ly/save.ini";
|
||||
var save_path_alloc = false;
|
||||
defer {
|
||||
if (save_path_alloc) allocator.free(save_path);
|
||||
if (save_path_alloc) allocator.free(old_save_path);
|
||||
}
|
||||
|
||||
const comment_characters = "#";
|
||||
@@ -178,18 +184,9 @@ pub fn main() !void {
|
||||
}) catch Lang{};
|
||||
|
||||
if (config.save) {
|
||||
save_path = try std.fmt.allocPrint(allocator, "{s}{s}save.ini", .{ s, trailing_slash });
|
||||
save_path = try std.fmt.allocPrint(allocator, "{s}{s}save.txt", .{ s, trailing_slash });
|
||||
old_save_path = try std.fmt.allocPrint(allocator, "{s}{s}save.ini", .{ s, trailing_slash });
|
||||
save_path_alloc = true;
|
||||
|
||||
var user_buf: [32]u8 = undefined;
|
||||
save = save_ini.readFileToStruct(save_path, .{
|
||||
.fieldHandler = null,
|
||||
.comment_characters = comment_characters,
|
||||
}) catch migrator.tryMigrateSaveFile(&user_buf);
|
||||
}
|
||||
|
||||
if (maybe_config_load_error == null) {
|
||||
migrator.lateConfigFieldHandler(&config);
|
||||
}
|
||||
} else {
|
||||
const config_path = build_options.config_directory ++ "/ly/config.ini";
|
||||
@@ -210,17 +207,47 @@ pub fn main() !void {
|
||||
.fieldHandler = null,
|
||||
.comment_characters = comment_characters,
|
||||
}) catch Lang{};
|
||||
}
|
||||
|
||||
if (config.save) {
|
||||
var user_buf: [32]u8 = undefined;
|
||||
save = save_ini.readFileToStruct(save_path, .{
|
||||
.fieldHandler = null,
|
||||
.comment_characters = comment_characters,
|
||||
}) catch migrator.tryMigrateSaveFile(&user_buf);
|
||||
}
|
||||
if (maybe_config_load_error == null) {
|
||||
migrator.lateConfigFieldHandler(&config);
|
||||
}
|
||||
|
||||
if (maybe_config_load_error == null) {
|
||||
migrator.lateConfigFieldHandler(&config);
|
||||
var usernames = try getAllUsernames(allocator, config.login_defs_path);
|
||||
defer {
|
||||
for (usernames.items) |username| allocator.free(username);
|
||||
usernames.deinit(allocator);
|
||||
}
|
||||
|
||||
if (config.save) read_save_file: {
|
||||
old_save_file_exists = migrator.tryMigrateIniSaveFile(allocator, &old_save_ini, old_save_path, &saved_users, usernames.items) catch break :read_save_file;
|
||||
|
||||
// Don't read the new save file if the old one still exists
|
||||
if (old_save_file_exists) break :read_save_file;
|
||||
|
||||
var save_file = std.fs.cwd().openFile(save_path, .{}) catch break :read_save_file;
|
||||
defer save_file.close();
|
||||
|
||||
var file_buffer: [256]u8 = undefined;
|
||||
var file_reader = save_file.reader(&file_buffer);
|
||||
var reader = &file_reader.interface;
|
||||
|
||||
const last_username_index_str = reader.takeDelimiterInclusive('\n') catch break :read_save_file;
|
||||
saved_users.last_username_index = std.fmt.parseInt(usize, last_username_index_str[0..(last_username_index_str.len - 1)], 10) catch break :read_save_file;
|
||||
|
||||
while (reader.seek < reader.buffer.len) {
|
||||
const line = reader.takeDelimiterInclusive('\n') catch break;
|
||||
|
||||
var user = std.mem.splitScalar(u8, line[0..(line.len - 1)], ':');
|
||||
const username = user.next() orelse continue;
|
||||
const session_index_str = user.next() orelse continue;
|
||||
|
||||
const session_index = std.fmt.parseInt(usize, session_index_str, 10) catch continue;
|
||||
|
||||
try saved_users.user_list.append(allocator, .{
|
||||
.username = username,
|
||||
.session_index = session_index,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +372,9 @@ pub fn main() !void {
|
||||
try log_writer.print("failed to set numlock: {s}\n", .{@errorName(err)});
|
||||
};
|
||||
|
||||
var session = Session.init(allocator, &buffer);
|
||||
var login: UserList = undefined;
|
||||
|
||||
var session = Session.init(allocator, &buffer, &login);
|
||||
defer session.deinit();
|
||||
|
||||
addOtherEnvironment(&session, lang, .shell, null) catch |err| {
|
||||
@@ -396,12 +425,6 @@ pub fn main() !void {
|
||||
try crawl(&session, lang, dir, .custom);
|
||||
}
|
||||
|
||||
var usernames = try getAllUsernames(allocator, config.login_defs_path);
|
||||
defer {
|
||||
for (usernames.items) |username| allocator.free(username);
|
||||
usernames.deinit(allocator);
|
||||
}
|
||||
|
||||
if (usernames.items.len == 0) {
|
||||
// If we have no usernames, simply add an error to the info line.
|
||||
// This effectively means you can't login, since there would be no local
|
||||
@@ -411,7 +434,7 @@ pub fn main() !void {
|
||||
try log_writer.writeAll("no users found\n");
|
||||
}
|
||||
|
||||
var login = try UserList.init(allocator, &buffer, usernames);
|
||||
login = try UserList.init(allocator, &buffer, usernames, &saved_users, &session);
|
||||
defer login.deinit();
|
||||
|
||||
var password = Text.init(allocator, &buffer, true, config.asterisk);
|
||||
@@ -422,23 +445,21 @@ pub fn main() !void {
|
||||
|
||||
// Load last saved username and desktop selection, if any
|
||||
if (config.save) {
|
||||
if (save.user) |user| {
|
||||
if (saved_users.last_username_index) |index| {
|
||||
const user = saved_users.user_list.items[index];
|
||||
|
||||
// Find user with saved name, and switch over to it
|
||||
// If it doesn't exist (anymore), we don't change the value
|
||||
// Note that we could instead save the username index, but migrating
|
||||
// from the raw username to an index is non-trivial and I'm lazy :P
|
||||
for (usernames.items, 0..) |username, i| {
|
||||
if (std.mem.eql(u8, username, user)) {
|
||||
if (std.mem.eql(u8, username, user.username)) {
|
||||
login.label.current = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
active_input = .password;
|
||||
}
|
||||
|
||||
if (save.session_index) |session_index| {
|
||||
if (session_index < session.label.list.items.len) session.label.current = session_index;
|
||||
if (user.session_index < session.label.list.items.len) session.label.current = user.session_index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -853,22 +874,33 @@ pub fn main() !void {
|
||||
_ = termbox.tb_present();
|
||||
|
||||
if (config.save) save_last_settings: {
|
||||
var file = std.fs.cwd().createFile(save_path, .{}) catch break :save_last_settings;
|
||||
// It isn't worth cluttering the code with precise error
|
||||
// handling, so let's just report a generic error message,
|
||||
// that should be good enough for debugging anyway.
|
||||
errdefer log_writer.writeAll("failed to save current user data\n") catch {};
|
||||
|
||||
var file = std.fs.cwd().createFile(save_path, .{}) catch |err| {
|
||||
log_writer.print("failed to create save file: {s}\n", .{@errorName(err)}) catch break :save_last_settings;
|
||||
break :save_last_settings;
|
||||
};
|
||||
defer file.close();
|
||||
|
||||
var file_buffer: [64]u8 = undefined;
|
||||
var file_buffer: [256]u8 = undefined;
|
||||
var file_writer = file.writer(&file_buffer);
|
||||
var writer = &file_writer.interface;
|
||||
|
||||
const save_data = Save{
|
||||
.user = login.getCurrentUser(),
|
||||
.session_index = session.label.current,
|
||||
};
|
||||
ini.writeFromStruct(save_data, writer, null, .{}) catch break :save_last_settings;
|
||||
try writer.print("{d}\n", .{login.label.current});
|
||||
for (saved_users.user_list.items) |user| {
|
||||
try writer.print("{s}:{d}\n", .{ user.username, user.session_index });
|
||||
}
|
||||
try writer.flush();
|
||||
|
||||
// Delete previous save file if it exists
|
||||
if (migrator.maybe_save_file) |path| std.fs.cwd().deleteFile(path) catch {};
|
||||
if (migrator.maybe_save_file) |path| {
|
||||
std.fs.cwd().deleteFile(path) catch {};
|
||||
} else if (old_save_file_exists) {
|
||||
std.fs.cwd().deleteFile(old_save_path) catch {};
|
||||
}
|
||||
}
|
||||
|
||||
var shared_err = try SharedError.init();
|
||||
@@ -877,7 +909,7 @@ pub fn main() !void {
|
||||
{
|
||||
session_pid = try std.posix.fork();
|
||||
if (session_pid == 0) {
|
||||
const current_environment = session.label.list.items[session.label.current];
|
||||
const current_environment = session.label.list.items[session.label.current].environment;
|
||||
const auth_options = auth.AuthOptions{
|
||||
.tty = active_tty,
|
||||
.service_name = config.service_name,
|
||||
@@ -898,7 +930,7 @@ pub fn main() !void {
|
||||
};
|
||||
std.posix.sigaction(std.posix.SIG.CHLD, &tty_control_transfer_act, null);
|
||||
|
||||
auth.authenticate(allocator, log_writer, auth_options, current_environment, login.getCurrentUser(), password.text.items) catch |err| {
|
||||
auth.authenticate(allocator, log_writer, auth_options, current_environment, login.getCurrentUsername(), password.text.items) catch |err| {
|
||||
shared_err.writeError(err);
|
||||
std.process.exit(1);
|
||||
};
|
||||
@@ -1026,7 +1058,7 @@ fn addOtherEnvironment(session: *Session, lang: Lang, display_server: DisplaySer
|
||||
.name = name,
|
||||
.xdg_session_desktop = null,
|
||||
.xdg_desktop_names = null,
|
||||
.cmd = exec orelse "",
|
||||
.cmd = exec,
|
||||
.specifier = lang.other,
|
||||
.display_server = display_server,
|
||||
.is_terminal = display_server == .shell,
|
||||
|
||||
Reference in New Issue
Block a user