mirror of https://github.com/fairyglade/ly.git
List all users in the system (fixes #373)
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
parent
97efac0cd1
commit
1d4e32ba82
|
@ -184,6 +184,9 @@ load = true
|
||||||
# You can also set environment variables in there, they'll persist until logout
|
# You can also set environment variables in there, they'll persist until logout
|
||||||
login_cmd = null
|
login_cmd = null
|
||||||
|
|
||||||
|
# Path for login.defs file (used for listing all local users on the system)
|
||||||
|
login_defs_path = /etc/login.defs
|
||||||
|
|
||||||
# Command executed when logging out
|
# Command executed when logging out
|
||||||
# If null, no command will be executed
|
# If null, no command will be executed
|
||||||
# Important: the session will already be terminated when this command is executed, so
|
# Important: the session will already be terminated when this command is executed, so
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = فشل في جلب معلومات المستخدم
|
||||||
err_sleep = فشل في تنفيذ أمر sleep
|
err_sleep = فشل في تنفيذ أمر sleep
|
||||||
|
|
||||||
err_tty_ctrl = فشل في نقل تحكم الطرفية (TTY)
|
err_tty_ctrl = فشل في نقل تحكم الطرفية (TTY)
|
||||||
|
|
||||||
err_user_gid = فشل في تعيين معرّف المجموعة (GID) للمستخدم
|
err_user_gid = فشل في تعيين معرّف المجموعة (GID) للمستخدم
|
||||||
err_user_init = فشل في تهيئة بيانات المستخدم
|
err_user_init = فشل في تهيئة بيانات المستخدم
|
||||||
err_user_uid = فشل في تعيين معرّف المستخدم (UID)
|
err_user_uid = فشل في تعيين معرّف المستخدم (UID)
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = error en obtenir la informació de l'usuari
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = error en establir el GID de l'usuari
|
err_user_gid = error en establir el GID de l'usuari
|
||||||
err_user_init = error en inicialitzar usuari
|
err_user_init = error en inicialitzar usuari
|
||||||
err_user_uid = error en establir l'UID de l'usuari
|
err_user_uid = error en establir l'UID de l'usuari
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = nelze získat informace o uživateli
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = nastavení GID uživatele selhalo
|
err_user_gid = nastavení GID uživatele selhalo
|
||||||
err_user_init = inicializace uživatele selhala
|
err_user_init = inicializace uživatele selhala
|
||||||
err_user_uid = nastavení UID uživateli selhalo
|
err_user_uid = nastavení UID uživateli selhalo
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = Abrufen der Benutzerinformationen fehlgeschlagen
|
||||||
err_sleep = Sleep-Befehl fehlgeschlagen
|
err_sleep = Sleep-Befehl fehlgeschlagen
|
||||||
|
|
||||||
err_tty_ctrl = Fehler bei der TTY-Uebergabe
|
err_tty_ctrl = Fehler bei der TTY-Uebergabe
|
||||||
|
|
||||||
err_user_gid = Fehler beim Setzen der Gruppen-ID
|
err_user_gid = Fehler beim Setzen der Gruppen-ID
|
||||||
err_user_init = Nutzer-Initialisierung fehlgeschlagen
|
err_user_init = Nutzer-Initialisierung fehlgeschlagen
|
||||||
err_user_uid = Setzen der Benutzer-ID fehlgeschlagen
|
err_user_uid = Setzen der Benutzer-ID fehlgeschlagen
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = failed to get user info
|
||||||
err_sleep = failed to execute sleep command
|
err_sleep = failed to execute sleep command
|
||||||
err_switch_tty = failed to switch tty
|
err_switch_tty = failed to switch tty
|
||||||
err_tty_ctrl = tty control transfer failed
|
err_tty_ctrl = tty control transfer failed
|
||||||
|
err_no_users = no users found
|
||||||
err_user_gid = failed to set user GID
|
err_user_gid = failed to set user GID
|
||||||
err_user_init = failed to initialize user
|
err_user_init = failed to initialize user
|
||||||
err_user_uid = failed to set user UID
|
err_user_uid = failed to set user UID
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = error al obtener la información del usuario
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = error al establecer el GID del usuario
|
err_user_gid = error al establecer el GID del usuario
|
||||||
err_user_init = error al inicializar usuario
|
err_user_init = error al inicializar usuario
|
||||||
err_user_uid = error al establecer el UID del usuario
|
err_user_uid = error al establecer el UID del usuario
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = échec de lecture des infos utilisateur
|
||||||
err_sleep = échec de l'exécution de la commande de veille
|
err_sleep = échec de l'exécution de la commande de veille
|
||||||
err_switch_tty = échec du changement de terminal
|
err_switch_tty = échec du changement de terminal
|
||||||
err_tty_ctrl = échec du transfert de contrôle du terminal
|
err_tty_ctrl = échec du transfert de contrôle du terminal
|
||||||
|
err_no_users = aucun utilisateur trouvé
|
||||||
err_user_gid = échec de modification du GID
|
err_user_gid = échec de modification du GID
|
||||||
err_user_init = échec d'initialisation de l'utilisateur
|
err_user_init = échec d'initialisation de l'utilisateur
|
||||||
err_user_uid = échec de modification du UID
|
err_user_uid = échec de modification du UID
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = impossibile ottenere dati utente
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = impossibile impostare GID utente
|
err_user_gid = impossibile impostare GID utente
|
||||||
err_user_init = impossibile inizializzare utente
|
err_user_init = impossibile inizializzare utente
|
||||||
err_user_uid = impossible impostare UID utente
|
err_user_uid = impossible impostare UID utente
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = nie udało się uzyskać informacji o użytkowniku
|
||||||
err_sleep = nie udało się wykonać polecenia sleep
|
err_sleep = nie udało się wykonać polecenia sleep
|
||||||
|
|
||||||
err_tty_ctrl = nie udało się przekazać kontroli tty
|
err_tty_ctrl = nie udało się przekazać kontroli tty
|
||||||
|
|
||||||
err_user_gid = nie udało się ustawić GID użytkownika
|
err_user_gid = nie udało się ustawić GID użytkownika
|
||||||
err_user_init = nie udało się zainicjalizować użytkownika
|
err_user_init = nie udało się zainicjalizować użytkownika
|
||||||
err_user_uid = nie udało się ustawić UID użytkownika
|
err_user_uid = nie udało się ustawić UID użytkownika
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = erro ao obter informação do utilizador
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = erro ao definir o GID do utilizador
|
err_user_gid = erro ao definir o GID do utilizador
|
||||||
err_user_init = erro ao iniciar o utilizador
|
err_user_init = erro ao iniciar o utilizador
|
||||||
err_user_uid = erro ao definir o UID do utilizador
|
err_user_uid = erro ao definir o UID do utilizador
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = não foi possível obter informações do usuário
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = não foi possível definir o GID do usuário
|
err_user_gid = não foi possível definir o GID do usuário
|
||||||
err_user_init = não foi possível iniciar o usuário
|
err_user_init = não foi possível iniciar o usuário
|
||||||
err_user_uid = não foi possível definir o UID do usuário
|
err_user_uid = não foi possível definir o UID do usuário
|
||||||
|
|
|
@ -49,6 +49,7 @@ err_perm_user = nu s-a putut face downgrade permisiunilor de utilizator
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
login = utilizator
|
login = utilizator
|
||||||
logout = opreşte sesiunea
|
logout = opreşte sesiunea
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = не удалось получить информацию о пол
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = не удалось установить GID пользователя
|
err_user_gid = не удалось установить GID пользователя
|
||||||
err_user_init = не удалось инициализировать пользователя
|
err_user_init = не удалось инициализировать пользователя
|
||||||
err_user_uid = не удалось установить UID пользователя
|
err_user_uid = не удалось установить UID пользователя
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = neuspijesno skupljanje informacija o korisniku
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = neuspijesno postavljanje korisničkog GID-a
|
err_user_gid = neuspijesno postavljanje korisničkog GID-a
|
||||||
err_user_init = neuspijensa inicijalizacija korisnika
|
err_user_init = neuspijensa inicijalizacija korisnika
|
||||||
err_user_uid = neuspijesno postavljanje UID-a korisnika
|
err_user_uid = neuspijesno postavljanje UID-a korisnika
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = misslyckades att hämta användarinfo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = misslyckades att ställa in användar-GID
|
err_user_gid = misslyckades att ställa in användar-GID
|
||||||
err_user_init = misslyckades att initialisera användaren
|
err_user_init = misslyckades att initialisera användaren
|
||||||
err_user_uid = misslyckades att ställa in användar-UID
|
err_user_uid = misslyckades att ställa in användar-UID
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = kullanici bilgileri alinamadi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = kullanici icin GID ayarlanamadi
|
err_user_gid = kullanici icin GID ayarlanamadi
|
||||||
err_user_init = kullanici oturumu baslatilamadi
|
err_user_init = kullanici oturumu baslatilamadi
|
||||||
err_user_uid = kullanici icin UID ayarlanamadi
|
err_user_uid = kullanici icin UID ayarlanamadi
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = не вдалося отримати дані користувача
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = не вдалося змінити GID користувача
|
err_user_gid = не вдалося змінити GID користувача
|
||||||
err_user_init = не вдалося ініціалізувати користувача
|
err_user_init = не вдалося ініціалізувати користувача
|
||||||
err_user_uid = не вдалося змінити UID користувача
|
err_user_uid = не вдалося змінити UID користувача
|
||||||
|
|
|
@ -41,6 +41,7 @@ err_pwnam = 获取用户信息失败
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_user_gid = 设置用户GID失败
|
err_user_gid = 设置用户GID失败
|
||||||
err_user_init = 初始化用户失败
|
err_user_init = 初始化用户失败
|
||||||
err_user_uid = 设置用户UID失败
|
err_user_uid = 设置用户UID失败
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
// We set both values to 0 by default so that, in case they aren't present in
|
||||||
|
// the login.defs for some reason, then only the root username will be shown
|
||||||
|
uid_min: std.c.uid_t = 0,
|
||||||
|
uid_max: std.c.uid_t = 0,
|
|
@ -50,6 +50,7 @@ input_len: u8 = 34,
|
||||||
lang: []const u8 = "en",
|
lang: []const u8 = "en",
|
||||||
load: bool = true,
|
load: bool = true,
|
||||||
login_cmd: ?[]const u8 = null,
|
login_cmd: ?[]const u8 = null,
|
||||||
|
login_defs_path: []const u8 = "/etc/login.defs",
|
||||||
logout_cmd: ?[]const u8 = null,
|
logout_cmd: ?[]const u8 = null,
|
||||||
margin_box_h: u8 = 2,
|
margin_box_h: u8 = 2,
|
||||||
margin_box_v: u8 = 1,
|
margin_box_v: u8 = 1,
|
||||||
|
|
|
@ -46,6 +46,7 @@ err_pwnam: []const u8 = "failed to get user info",
|
||||||
err_sleep: []const u8 = "failed to execute sleep command",
|
err_sleep: []const u8 = "failed to execute sleep command",
|
||||||
err_switch_tty: []const u8 = "failed to switch tty",
|
err_switch_tty: []const u8 = "failed to switch tty",
|
||||||
err_tty_ctrl: []const u8 = "tty control transfer failed",
|
err_tty_ctrl: []const u8 = "tty control transfer failed",
|
||||||
|
err_no_users: []const u8 = "no users found",
|
||||||
err_user_gid: []const u8 = "failed to set user GID",
|
err_user_gid: []const u8 = "failed to set user GID",
|
||||||
err_user_init: []const u8 = "failed to initialize user",
|
err_user_init: []const u8 = "failed to initialize user",
|
||||||
err_user_uid: []const u8 = "failed to set user UID",
|
err_user_uid: []const u8 = "failed to set user UID",
|
||||||
|
|
124
src/main.zig
124
src/main.zig
|
@ -18,12 +18,15 @@ const TerminalBuffer = @import("tui/TerminalBuffer.zig");
|
||||||
const Session = @import("tui/components/Session.zig");
|
const Session = @import("tui/components/Session.zig");
|
||||||
const Text = @import("tui/components/Text.zig");
|
const Text = @import("tui/components/Text.zig");
|
||||||
const InfoLine = @import("tui/components/InfoLine.zig");
|
const InfoLine = @import("tui/components/InfoLine.zig");
|
||||||
|
const UserList = @import("tui/components/UserList.zig");
|
||||||
const Config = @import("config/Config.zig");
|
const Config = @import("config/Config.zig");
|
||||||
const Lang = @import("config/Lang.zig");
|
const Lang = @import("config/Lang.zig");
|
||||||
const Save = @import("config/Save.zig");
|
const Save = @import("config/Save.zig");
|
||||||
const migrator = @import("config/migrator.zig");
|
const migrator = @import("config/migrator.zig");
|
||||||
const SharedError = @import("SharedError.zig");
|
const SharedError = @import("SharedError.zig");
|
||||||
|
const UidRange = @import("UidRange.zig");
|
||||||
|
|
||||||
|
const StringList = std.ArrayListUnmanaged([]const u8);
|
||||||
const Ini = ini.Ini;
|
const Ini = ini.Ini;
|
||||||
const DisplayServer = enums.DisplayServer;
|
const DisplayServer = enums.DisplayServer;
|
||||||
const Entry = Environment.Entry;
|
const Entry = Environment.Entry;
|
||||||
|
@ -308,7 +311,21 @@ pub fn main() !void {
|
||||||
try crawl(&session, lang, dir, .custom);
|
try crawl(&session, lang, dir, .custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
var login = Text.init(allocator, &buffer, false, null);
|
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
|
||||||
|
// accounts *and* no root account...but at this point, if that's the
|
||||||
|
// case, you have bigger problems to deal with in the first place. :D
|
||||||
|
try info_line.addMessage(lang.err_no_users, config.error_bg, config.error_fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var login = try UserList.init(allocator, &buffer, usernames);
|
||||||
defer login.deinit();
|
defer login.deinit();
|
||||||
|
|
||||||
var password = Text.init(allocator, &buffer, true, config.asterisk);
|
var password = Text.init(allocator, &buffer, true, config.asterisk);
|
||||||
|
@ -320,9 +337,17 @@ pub fn main() !void {
|
||||||
// Load last saved username and desktop selection, if any
|
// Load last saved username and desktop selection, if any
|
||||||
if (config.load) {
|
if (config.load) {
|
||||||
if (save.user) |user| {
|
if (save.user) |user| {
|
||||||
try login.text.appendSlice(login.allocator, user);
|
// Find user with saved name, and switch over to it
|
||||||
login.end = user.len;
|
// If it doesn't exist (anymore), we don't change the value
|
||||||
login.cursor = login.end;
|
// 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)) {
|
||||||
|
login.label.current = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
active_input = .password;
|
active_input = .password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,15 +363,13 @@ pub fn main() !void {
|
||||||
const coordinates = buffer.calculateComponentCoordinates();
|
const coordinates = buffer.calculateComponentCoordinates();
|
||||||
info_line.label.position(coordinates.start_x, coordinates.y, coordinates.full_visible_length, null);
|
info_line.label.position(coordinates.start_x, coordinates.y, coordinates.full_visible_length, null);
|
||||||
session.label.position(coordinates.x, coordinates.y + 2, coordinates.visible_length, config.text_in_center);
|
session.label.position(coordinates.x, coordinates.y + 2, coordinates.visible_length, config.text_in_center);
|
||||||
login.position(coordinates.x, coordinates.y + 4, coordinates.visible_length);
|
login.label.position(coordinates.x, coordinates.y + 4, coordinates.visible_length, config.text_in_center);
|
||||||
password.position(coordinates.x, coordinates.y + 6, coordinates.visible_length);
|
password.position(coordinates.x, coordinates.y + 6, coordinates.visible_length);
|
||||||
|
|
||||||
switch (active_input) {
|
switch (active_input) {
|
||||||
.info_line => info_line.label.handle(null, insert_mode),
|
.info_line => info_line.label.handle(null, insert_mode),
|
||||||
.session => session.label.handle(null, insert_mode),
|
.session => session.label.handle(null, insert_mode),
|
||||||
.login => login.handle(null, insert_mode) catch {
|
.login => login.label.handle(null, insert_mode),
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
|
||||||
},
|
|
||||||
.password => password.handle(null, insert_mode) catch {
|
.password => password.handle(null, insert_mode) catch {
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
||||||
},
|
},
|
||||||
|
@ -464,7 +487,7 @@ pub fn main() !void {
|
||||||
const coordinates = buffer.calculateComponentCoordinates();
|
const coordinates = buffer.calculateComponentCoordinates();
|
||||||
info_line.label.position(coordinates.start_x, coordinates.y, coordinates.full_visible_length, null);
|
info_line.label.position(coordinates.start_x, coordinates.y, coordinates.full_visible_length, null);
|
||||||
session.label.position(coordinates.x, coordinates.y + 2, coordinates.visible_length, config.text_in_center);
|
session.label.position(coordinates.x, coordinates.y + 2, coordinates.visible_length, config.text_in_center);
|
||||||
login.position(coordinates.x, coordinates.y + 4, coordinates.visible_length);
|
login.label.position(coordinates.x, coordinates.y + 4, coordinates.visible_length, config.text_in_center);
|
||||||
password.position(coordinates.x, coordinates.y + 6, coordinates.visible_length);
|
password.position(coordinates.x, coordinates.y + 6, coordinates.visible_length);
|
||||||
|
|
||||||
resolution_changed = false;
|
resolution_changed = false;
|
||||||
|
@ -473,9 +496,7 @@ pub fn main() !void {
|
||||||
switch (active_input) {
|
switch (active_input) {
|
||||||
.info_line => info_line.label.handle(null, insert_mode),
|
.info_line => info_line.label.handle(null, insert_mode),
|
||||||
.session => session.label.handle(null, insert_mode),
|
.session => session.label.handle(null, insert_mode),
|
||||||
.login => login.handle(null, insert_mode) catch {
|
.login => login.label.handle(null, insert_mode),
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
|
||||||
},
|
|
||||||
.password => password.handle(null, insert_mode) catch {
|
.password => password.handle(null, insert_mode) catch {
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
||||||
},
|
},
|
||||||
|
@ -571,7 +592,7 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
session.label.draw();
|
session.label.draw();
|
||||||
login.draw();
|
login.label.draw();
|
||||||
password.draw();
|
password.draw();
|
||||||
} else {
|
} else {
|
||||||
std.Thread.sleep(std.time.ns_per_ms * 10);
|
std.Thread.sleep(std.time.ns_per_ms * 10);
|
||||||
|
@ -660,10 +681,7 @@ pub fn main() !void {
|
||||||
},
|
},
|
||||||
termbox.TB_KEY_CTRL_C => run = false,
|
termbox.TB_KEY_CTRL_C => run = false,
|
||||||
termbox.TB_KEY_CTRL_U => {
|
termbox.TB_KEY_CTRL_U => {
|
||||||
if (active_input == .login) {
|
if (active_input == .password) {
|
||||||
login.clear();
|
|
||||||
update = true;
|
|
||||||
} else if (active_input == .password) {
|
|
||||||
password.clear();
|
password.clear();
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
|
@ -726,7 +744,7 @@ pub fn main() !void {
|
||||||
defer file.close();
|
defer file.close();
|
||||||
|
|
||||||
const save_data = Save{
|
const save_data = Save{
|
||||||
.user = login.text.items,
|
.user = login.getCurrentUser(),
|
||||||
.session_index = session.label.current,
|
.session_index = session.label.current,
|
||||||
};
|
};
|
||||||
ini.writeFromStruct(save_data, file.writer(), null, .{}) catch break :save_last_settings;
|
ini.writeFromStruct(save_data, file.writer(), null, .{}) catch break :save_last_settings;
|
||||||
|
@ -739,7 +757,7 @@ pub fn main() !void {
|
||||||
defer shared_err.deinit();
|
defer shared_err.deinit();
|
||||||
|
|
||||||
{
|
{
|
||||||
const login_text = try allocator.dupeZ(u8, login.text.items);
|
const login_text = try allocator.dupeZ(u8, login.getCurrentUser());
|
||||||
defer allocator.free(login_text);
|
defer allocator.free(login_text);
|
||||||
const password_text = try allocator.dupeZ(u8, password.text.items);
|
const password_text = try allocator.dupeZ(u8, password.text.items);
|
||||||
defer allocator.free(password_text);
|
defer allocator.free(password_text);
|
||||||
|
@ -845,9 +863,7 @@ pub fn main() !void {
|
||||||
switch (active_input) {
|
switch (active_input) {
|
||||||
.info_line => info_line.label.handle(&event, insert_mode),
|
.info_line => info_line.label.handle(&event, insert_mode),
|
||||||
.session => session.label.handle(&event, insert_mode),
|
.session => session.label.handle(&event, insert_mode),
|
||||||
.login => login.handle(&event, insert_mode) catch {
|
.login => login.label.handle(&event, insert_mode),
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
|
||||||
},
|
|
||||||
.password => password.handle(&event, insert_mode) catch {
|
.password => password.handle(&event, insert_mode) catch {
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
||||||
},
|
},
|
||||||
|
@ -934,6 +950,70 @@ fn crawl(session: *Session, lang: Lang, path: []const u8, display_server: Displa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getAllUsernames(allocator: std.mem.Allocator, login_defs_path: []const u8) !StringList {
|
||||||
|
const uid_range = try getUserIdRange(allocator, login_defs_path);
|
||||||
|
|
||||||
|
var usernames: StringList = .empty;
|
||||||
|
var maybe_entry = interop.pwd.getpwent();
|
||||||
|
|
||||||
|
while (maybe_entry != null) {
|
||||||
|
const entry = maybe_entry.*;
|
||||||
|
|
||||||
|
// We check if the UID is equal to 0 because we always want to add root
|
||||||
|
// as a username (even if you can't log into it)
|
||||||
|
if (entry.pw_uid >= uid_range.uid_min and entry.pw_uid <= uid_range.uid_max or entry.pw_uid == 0) {
|
||||||
|
const pw_name_slice = entry.pw_name[0..std.mem.len(entry.pw_name)];
|
||||||
|
const username = try allocator.dupe(u8, pw_name_slice);
|
||||||
|
|
||||||
|
try usernames.append(allocator, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
maybe_entry = interop.pwd.getpwent();
|
||||||
|
}
|
||||||
|
|
||||||
|
interop.pwd.endpwent();
|
||||||
|
return usernames;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is very bad parsing, but we only need to get 2 values... and the format
|
||||||
|
// of the file doesn't seem to be standard? So this should be fine...
|
||||||
|
fn getUserIdRange(allocator: std.mem.Allocator, login_defs_path: []const u8) !UidRange {
|
||||||
|
const login_defs_file = try std.fs.cwd().openFile(login_defs_path, .{});
|
||||||
|
defer login_defs_file.close();
|
||||||
|
|
||||||
|
const login_defs_buffer = try login_defs_file.readToEndAlloc(allocator, std.math.maxInt(u16));
|
||||||
|
defer allocator.free(login_defs_buffer);
|
||||||
|
|
||||||
|
var iterator = std.mem.splitScalar(u8, login_defs_buffer, '\n');
|
||||||
|
var uid_range = UidRange{};
|
||||||
|
|
||||||
|
while (iterator.next()) |line| {
|
||||||
|
const trimmed_line = std.mem.trim(u8, line, " \n\r\t");
|
||||||
|
|
||||||
|
if (std.mem.startsWith(u8, trimmed_line, "UID_MIN")) {
|
||||||
|
uid_range.uid_min = try parseValue(std.c.uid_t, "UID_MIN", trimmed_line);
|
||||||
|
} else if (std.mem.startsWith(u8, trimmed_line, "UID_MAX")) {
|
||||||
|
uid_range.uid_max = try parseValue(std.c.uid_t, "UID_MAX", trimmed_line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uid_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseValue(comptime T: type, name: []const u8, buffer: []const u8) !T {
|
||||||
|
var iterator = std.mem.splitAny(u8, buffer, " \t");
|
||||||
|
var maybe_value: ?T = null;
|
||||||
|
|
||||||
|
while (iterator.next()) |slice| {
|
||||||
|
// Skip the slice if it's empty (whitespace) or is the name of the
|
||||||
|
// property (e.g. UID_MIN or UID_MAX)
|
||||||
|
if (slice.len == 0 or std.mem.eql(u8, slice, name)) continue;
|
||||||
|
maybe_value = std.fmt.parseInt(T, slice, 10) catch continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return maybe_value orelse error.ValueNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
fn adjustBrightness(allocator: std.mem.Allocator, cmd: []const u8) !void {
|
fn adjustBrightness(allocator: std.mem.Allocator, cmd: []const u8) !void {
|
||||||
var brightness = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, allocator);
|
var brightness = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, allocator);
|
||||||
brightness.stdout_behavior = .Ignore;
|
brightness.stdout_behavior = .Ignore;
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const TerminalBuffer = @import("../TerminalBuffer.zig");
|
||||||
|
const generic = @import("generic.zig");
|
||||||
|
|
||||||
|
const StringList = std.ArrayListUnmanaged([]const u8);
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
const UsernameText = generic.CyclableLabel([]const u8);
|
||||||
|
|
||||||
|
const UserList = @This();
|
||||||
|
|
||||||
|
label: UsernameText,
|
||||||
|
|
||||||
|
pub fn init(allocator: Allocator, buffer: *TerminalBuffer, usernames: StringList) !UserList {
|
||||||
|
var userList = UserList{
|
||||||
|
.label = UsernameText.init(allocator, buffer, drawItem),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (usernames.items) |username| {
|
||||||
|
if (username.len == 0) continue;
|
||||||
|
|
||||||
|
try userList.label.addItem(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
return userList;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *UserList) void {
|
||||||
|
self.label.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getCurrentUser(self: UserList) []const u8 {
|
||||||
|
return self.label.list.items[self.label.current];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drawItem(label: *UsernameText, username: []const u8, _: usize, _: usize) bool {
|
||||||
|
const length = @min(username.len, label.visible_length - 3);
|
||||||
|
if (length == 0) return false;
|
||||||
|
|
||||||
|
const x = if (label.text_in_center) (label.x + (label.visible_length - username.len) / 2) else (label.x + 2);
|
||||||
|
label.first_char_x = x + username.len;
|
||||||
|
|
||||||
|
label.buffer.drawLabel(username, x, label.y);
|
||||||
|
return true;
|
||||||
|
}
|
Loading…
Reference in New Issue