diff --git a/src/animations/Doom.zig b/src/animations/Doom.zig index b4d435e..1583165 100644 --- a/src/animations/Doom.zig +++ b/src/animations/Doom.zig @@ -56,7 +56,7 @@ pub fn draw(self: Doom) void { const source = y * self.terminal_buffer.width + x; const random = (self.terminal_buffer.random.int(u16) % 7) & 3; - var dest = source - random + 1; + var dest = (source - @min(source, random)) + 1; if (self.terminal_buffer.width > dest) dest = 0 else dest -= self.terminal_buffer.width; const buffer_source = self.buffer[source]; diff --git a/src/auth.zig b/src/auth.zig index 4b061a5..3569e01 100644 --- a/src/auth.zig +++ b/src/auth.zig @@ -20,10 +20,9 @@ pub fn sessionSignalHandler(i: c_int) callconv(.C) void { if (child_pid > 0) _ = std.c.kill(child_pid, i); } -pub fn authenticate(config: Config, desktop: Desktop, login: [:0]const u8, password: [:0]const u8) !void { +pub fn authenticate(config: Config, current_environment: Desktop.Environment, login: [:0]const u8, password: [:0]const u8) !void { var tty_buffer: [2]u8 = undefined; const tty_str = try std.fmt.bufPrintZ(&tty_buffer, "{d}", .{config.tty}); - const current_environment = desktop.environments.items[desktop.current]; // Set the XDG environment variables setXdgSessionEnv(current_environment.display_server); @@ -40,6 +39,7 @@ pub fn authenticate(config: Config, desktop: Desktop, login: [:0]const u8, passw var status = interop.pam.pam_start(config.service_name.ptr, null, &conv, &handle); if (status != interop.pam.PAM_SUCCESS) return pamDiagnose(status); + defer _ = interop.pam.pam_end(handle, status); // Do the PAM routine status = interop.pam.pam_authenticate(handle, 0); @@ -50,9 +50,11 @@ pub fn authenticate(config: Config, desktop: Desktop, login: [:0]const u8, passw status = interop.pam.pam_setcred(handle, interop.pam.PAM_ESTABLISH_CRED); if (status != interop.pam.PAM_SUCCESS) return pamDiagnose(status); + defer status = interop.pam.pam_setcred(handle, interop.pam.PAM_DELETE_CRED); status = interop.pam.pam_open_session(handle, 0); if (status != interop.pam.PAM_SUCCESS) return pamDiagnose(status); + defer status = interop.pam.pam_close_session(handle, 0); var pwd: *interop.passwd = undefined; { @@ -83,6 +85,7 @@ pub fn authenticate(config: Config, desktop: Desktop, login: [:0]const u8, passw var entry: Utmp = std.mem.zeroes(Utmp); addUtmpEntry(&entry, pwd.pw_name, child_pid) catch {}; + defer removeUtmpEntry(&entry); // If we receive SIGTERM, forward it to child_pid const act = std.posix.Sigaction{ @@ -95,20 +98,8 @@ pub fn authenticate(config: Config, desktop: Desktop, login: [:0]const u8, passw // Wait for the session to stop _ = std.posix.waitpid(child_pid, 0); - removeUtmpEntry(&entry); - try resetTerminal(pwd.pw_shell, config.term_reset_cmd); - // Close the PAM session - status = interop.pam.pam_close_session(handle, 0); - if (status != 0) return pamDiagnose(status); - - status = interop.pam.pam_setcred(handle, interop.pam.PAM_DELETE_CRED); - if (status != 0) return pamDiagnose(status); - - status = interop.pam.pam_end(handle, status); - if (status != 0) return pamDiagnose(status); - if (shared_err.readError()) |err| return err; } @@ -118,8 +109,7 @@ fn startSession( handle: ?*interop.pam.pam_handle, current_environment: Desktop.Environment, ) !void { - var status: c_int = 0; - status = interop.initgroups(pwd.pw_name, pwd.pw_gid); + const status = interop.initgroups(pwd.pw_name, pwd.pw_gid); if (status != 0) return error.GroupInitializationFailed; std.posix.setgid(pwd.pw_gid) catch return error.SetUserGidFailed; @@ -352,7 +342,8 @@ fn xauth(display_name: [:0]u8, shell: [*:0]const u8, pw_dir: [*:0]const u8, xaut std.process.exit(1); } - _ = std.posix.waitpid(pid, 0); + const status = std.posix.waitpid(pid, 0); + if (status.status != 0) return error.XauthFailed; } fn executeShellCmd(shell: [*:0]const u8) !void { @@ -388,7 +379,7 @@ fn executeX11Cmd(shell: [*:0]const u8, pw_dir: [*:0]const u8, config: Config, de xcb = interop.xcb.xcb_connect(null, null); ok = interop.xcb.xcb_connection_has_error(xcb); std.posix.kill(pid, 0) catch |e| { - if (e == error.ProcessNotFound and ok != 0) return; + if (e == error.ProcessNotFound and ok != 0) return error.XcbConnectionFailed; }; } diff --git a/src/main.zig b/src/main.zig index bff277b..36a9164 100644 --- a/src/main.zig +++ b/src/main.zig @@ -305,16 +305,6 @@ pub fn main() !void { if (update) { // If the user entered a wrong password 10 times in a row, play a cascade animation, else update normally if (auth_fails < 10) { - switch (active_input) { - .session => desktop.handle(null, insert_mode), - .login => login.handle(null, insert_mode) catch { - try info_line.setText(lang.err_alloc); - }, - .password => password.handle(null, insert_mode) catch { - try info_line.setText(lang.err_alloc); - }, - } - termbox.tb_clear(); switch (config.animation) { @@ -325,7 +315,7 @@ pub fn main() !void { if (config.bigclock and buffer.box_height + (bigclock.HEIGHT + 2) * 2 < buffer.height) draw_big_clock: { const format = "%H:%M"; - const xo = buffer.width / 2 - (format.len * (bigclock.WIDTH + 1)) / 2; + const xo = buffer.width / 2 - @min(buffer.width, (format.len * (bigclock.WIDTH + 1))) / 2; const yo = (buffer.height - buffer.box_height) / 2 - bigclock.HEIGHT - 2; var clock_buf: [format.len + 1:0]u8 = undefined; @@ -341,6 +331,25 @@ pub fn main() !void { buffer.drawBoxCenter(!config.hide_borders, config.blank_box); + if (resolution_changed) { + const coordinates = buffer.calculateComponentCoordinates(); + desktop.position(coordinates.x, coordinates.y + 2, coordinates.visible_length); + login.position(coordinates.x, coordinates.y + 4, coordinates.visible_length); + password.position(coordinates.x, coordinates.y + 6, coordinates.visible_length); + + resolution_changed = false; + } + + switch (active_input) { + .session => desktop.handle(null, insert_mode), + .login => login.handle(null, insert_mode) catch { + try info_line.setText(lang.err_alloc); + }, + .password => password.handle(null, insert_mode) catch { + try info_line.setText(lang.err_alloc); + }, + } + if (config.clock) |clock| draw_clock: { var clock_buf: [32:0]u8 = undefined; const clock_str = interop.timeAsString(&clock_buf, clock) catch { @@ -349,7 +358,7 @@ pub fn main() !void { if (clock_str.len == 0) return error.FormattedTimeEmpty; - buffer.drawLabel(clock_str, buffer.width - clock_str.len, 0); + buffer.drawLabel(clock_str, buffer.width - @min(buffer.width, clock_str.len), 0); } const label_x = buffer.box_x + buffer.margin_box_h; @@ -408,15 +417,6 @@ pub fn main() !void { if (lock_state.capslock) buffer.drawLabel(lang.capslock, lock_state_x, lock_state_y); } - if (resolution_changed) { - const coordinates = buffer.calculateComponentCoordinates(); - desktop.position(coordinates.x, coordinates.y + 2, coordinates.visible_length); - login.position(coordinates.x, coordinates.y + 4, coordinates.visible_length); - password.position(coordinates.x, coordinates.y + 6, coordinates.visible_length); - - resolution_changed = false; - } - desktop.draw(); login.draw(); password.drawMasked(config.asterisk); @@ -533,7 +533,8 @@ pub fn main() !void { session_pid = try std.posix.fork(); if (session_pid == 0) { - auth.authenticate(config, desktop, login_text, password_text) catch |err| { + const current_environment = desktop.environments.items[desktop.current]; + auth.authenticate(config, current_environment, login_text, password_text) catch |err| { shared_err.writeError(err); std.process.exit(1); }; diff --git a/src/tui/TerminalBuffer.zig b/src/tui/TerminalBuffer.zig index 8e95886..0a746a6 100644 --- a/src/tui/TerminalBuffer.zig +++ b/src/tui/TerminalBuffer.zig @@ -100,10 +100,11 @@ pub fn cascade(self: TerminalBuffer) bool { } pub fn drawBoxCenter(self: *TerminalBuffer, show_borders: bool, blank_box: bool) void { - const x1 = (self.width - self.box_width) / 2; - const y1 = (self.height - self.box_height) / 2; - const x2 = (self.width + self.box_width) / 2; - const y2 = (self.height + self.box_height) / 2; + if (self.width < 2 or self.height < 2) return; + const x1 = (self.width - @min(self.width - 2, self.box_width)) / 2; + const y1 = (self.height - @min(self.height - 2, self.box_height)) / 2; + const x2 = (self.width + @min(self.width, self.box_width)) / 2; + const y2 = (self.height + @min(self.height, self.box_height)) / 2; self.box_x = x1; self.box_y = y1;