diff --git a/res/config.ini b/res/config.ini index 2e015c1..f56bcc6 100644 --- a/res/config.ini +++ b/res/config.ini @@ -231,6 +231,13 @@ hide_keyboard_locks = false # Remove version number from the top left corner hide_version_string = false +# Command executed when no input is detected for a certain time +# If null, no command will be executed +inactivity_cmd = null + +# Executes a command after a certain amount of seconds +inactivity_delay = 0 + # Initial text to show on the info line # If set to null, the info line defaults to the hostname initial_info_text = null diff --git a/res/lang/ar.ini b/res/lang/ar.ini index 0d733c5..6971326 100644 --- a/res/lang/ar.ini +++ b/res/lang/ar.ini @@ -21,6 +21,7 @@ err_envlist = فشل في جلب قائمة المتغيرات البيئية err_hostname = فشل في جلب اسم المضيف (Hostname) + err_mlock = فشل في تأمين ذاكرة كلمة المرور (mlock) err_null = مؤشر فارغ (Null pointer) err_numlock = فشل في ضبط Num Lock diff --git a/res/lang/bg.ini b/res/lang/bg.ini index 984d44d..aa24e02 100644 --- a/res/lang/bg.ini +++ b/res/lang/bg.ini @@ -19,6 +19,7 @@ err_envlist = неуспешно получаване на списъка с п err_get_active_tty = неуспешно откриване на активния TTY err_hibernate = неуспешно изпълнение на командата за хибернация err_hostname = неуспешно получаване на името на хоста + err_lock_state = неуспешно получаване на състоянието на заключване err_log = неуспешно отваряне на файла с дневника err_mlock = неуспешно заключване на паметта за паролата diff --git a/res/lang/cat.ini b/res/lang/cat.ini index 526e858..85dbe53 100644 --- a/res/lang/cat.ini +++ b/res/lang/cat.ini @@ -21,6 +21,7 @@ err_envlist = error en obtenir l'envlist err_hostname = error en obtenir el nom de l'amfitrió + err_mlock = error en bloquejar la memòria de clau err_null = punter nul err_numlock = error en establir el Bloq num diff --git a/res/lang/cs.ini b/res/lang/cs.ini index b42a52c..ff6943e 100644 --- a/res/lang/cs.ini +++ b/res/lang/cs.ini @@ -21,6 +21,7 @@ err_domain = neplatná doména err_hostname = nelze získat název hostitele + err_mlock = uzamčení paměti hesel selhalo err_null = nulový ukazatel diff --git a/res/lang/de.ini b/res/lang/de.ini index 02034b9..60ca3bd 100644 --- a/res/lang/de.ini +++ b/res/lang/de.ini @@ -21,6 +21,7 @@ err_envlist = Fehler beim Abrufen der Umgebungs-Variablen err_hostname = Abrufen des Hostnames fehlgeschlagen + err_mlock = Sperren des Passwortspeichers fehlgeschlagen err_null = Null Pointer err_numlock = Numlock konnte nicht aktiviert werden diff --git a/res/lang/en.ini b/res/lang/en.ini index 38ad8f5..b840816 100644 --- a/res/lang/en.ini +++ b/res/lang/en.ini @@ -19,6 +19,7 @@ err_envlist = failed to get envlist err_get_active_tty = failed to get active tty err_hibernate = failed to execute hibernate command err_hostname = failed to get hostname +err_inactivity = failed to execute inactivity command err_lock_state = failed to get lock state err_log = failed to open log file err_mlock = failed to lock password memory diff --git a/res/lang/es.ini b/res/lang/es.ini index e14aea9..fd3450a 100644 --- a/res/lang/es.ini +++ b/res/lang/es.ini @@ -21,6 +21,7 @@ err_domain = dominio inválido err_hostname = error al obtener el nombre de host + err_mlock = error al bloquear la contraseña de memoria err_null = puntero nulo diff --git a/res/lang/fr.ini b/res/lang/fr.ini index 8236184..17258de 100644 --- a/res/lang/fr.ini +++ b/res/lang/fr.ini @@ -19,6 +19,7 @@ err_envlist = échec de lecture de la liste d'environnement err_get_active_tty = échec de lecture du terminal actif err_hibernate = échec de l'exécution de la commande de veille prolongée err_hostname = échec de lecture du nom d'hôte +err_inactivity = échec de l'exécution de la commande d'inactivité err_lock_state = échec de lecture de l'état de verrouillage err_log = échec de l'ouverture du fichier de journal err_mlock = échec du verrouillage mémoire diff --git a/res/lang/it.ini b/res/lang/it.ini index 7c90a8f..d909609 100644 --- a/res/lang/it.ini +++ b/res/lang/it.ini @@ -21,6 +21,7 @@ err_domain = dominio non valido err_hostname = impossibile ottenere hostname + err_mlock = impossibile ottenere lock per la password in memoria err_null = puntatore nullo diff --git a/res/lang/ja_JP.ini b/res/lang/ja_JP.ini index cb299df..f77abd3 100644 --- a/res/lang/ja_JP.ini +++ b/res/lang/ja_JP.ini @@ -21,6 +21,7 @@ err_envlist = 環境変数リストの取得に失敗しました err_hostname = ホスト名の取得に失敗しました + err_mlock = パスワードメモリのロックに失敗しました err_null = ヌルポインタ err_numlock = NumLockの設定に失敗しました diff --git a/res/lang/lv.ini b/res/lang/lv.ini index 9b6f6cf..f572a99 100644 --- a/res/lang/lv.ini +++ b/res/lang/lv.ini @@ -19,6 +19,7 @@ err_envlist = neizdevās iegūt vides mainīgo sarakstu err_get_active_tty = neizdevās iegūt aktīvo tty err_hostname = neizdevās iegūt hostname + err_lock_state = neizdevās iegūt bloķēšanas stāvokli err_log = neizdevās atvērt žurnāla failu err_mlock = neizdevās bloķēt paroles atmiņu diff --git a/res/lang/pl.ini b/res/lang/pl.ini index 40c6895..aadc9ff 100644 --- a/res/lang/pl.ini +++ b/res/lang/pl.ini @@ -19,6 +19,7 @@ err_envlist = nie udało się pobrać listy zmiennych środowiskowych err_get_active_tty = nie udało się uzyskać aktywnego tty err_hostname = nie udało się uzyskać nazwy hosta + err_lock_state = nie udało się uzyskać stanu blokady err_log = nie udało się otworzyć pliku logu err_mlock = nie udało się zablokować pamięci haseł diff --git a/res/lang/pt.ini b/res/lang/pt.ini index f0cebd8..16d25a3 100644 --- a/res/lang/pt.ini +++ b/res/lang/pt.ini @@ -21,6 +21,7 @@ err_domain = domínio inválido err_hostname = erro ao obter o nome do host + err_mlock = erro de bloqueio de memória err_null = ponteiro nulo diff --git a/res/lang/pt_BR.ini b/res/lang/pt_BR.ini index a8eb90f..f8d0e26 100644 --- a/res/lang/pt_BR.ini +++ b/res/lang/pt_BR.ini @@ -21,6 +21,7 @@ err_domain = domínio inválido err_hostname = não foi possível obter o nome do host + err_mlock = bloqueio da memória de senha malsucedido err_null = ponteiro nulo diff --git a/res/lang/ro.ini b/res/lang/ro.ini index 8e5c6cf..9dfd75a 100644 --- a/res/lang/ro.ini +++ b/res/lang/ro.ini @@ -23,6 +23,7 @@ capslock = capslock + err_pam_abort = tranzacţie pam anulată diff --git a/res/lang/ru.ini b/res/lang/ru.ini index 26e9fbf..e47a41e 100644 --- a/res/lang/ru.ini +++ b/res/lang/ru.ini @@ -19,6 +19,7 @@ err_envlist = не удалось получить список переменн err_get_active_tty = не удалось получить активный tty err_hostname = не удалось получить имя хоста + err_lock_state = не удалось получить состояние lock err_log = не удалось открыть файл log err_mlock = сбой блокировки памяти diff --git a/res/lang/sr.ini b/res/lang/sr.ini index 5c9cb64..71c7ea1 100644 --- a/res/lang/sr.ini +++ b/res/lang/sr.ini @@ -21,6 +21,7 @@ err_domain = nevazeci domen err_hostname = neuspijesno trazenje hostname-a + err_mlock = neuspijesno zakljucavanje memorije lozinke err_null = null pokazivac diff --git a/res/lang/sv.ini b/res/lang/sv.ini index de329f1..661eb62 100644 --- a/res/lang/sv.ini +++ b/res/lang/sv.ini @@ -21,6 +21,7 @@ err_domain = okänd domän err_hostname = misslyckades att hämta värdnamn + err_mlock = misslyckades att låsa lösenordsminne err_null = nullpekare diff --git a/res/lang/tr.ini b/res/lang/tr.ini index 0bf1ffe..e351076 100644 --- a/res/lang/tr.ini +++ b/res/lang/tr.ini @@ -21,6 +21,7 @@ err_domain = gecersiz etki alani err_hostname = ana bilgisayar adi alinamadi + err_mlock = parola bellegi kilitlenemedi err_null = bos isaretci hatasi diff --git a/res/lang/uk.ini b/res/lang/uk.ini index 36e4ce3..f1dcf54 100644 --- a/res/lang/uk.ini +++ b/res/lang/uk.ini @@ -21,6 +21,7 @@ err_domain = недійсний домен err_hostname = не вдалося отримати ім'я хосту + err_mlock = збій блокування пам'яті err_null = нульовий вказівник diff --git a/res/lang/zh_CN.ini b/res/lang/zh_CN.ini index fd7b4ea..493ceac 100644 --- a/res/lang/zh_CN.ini +++ b/res/lang/zh_CN.ini @@ -21,6 +21,7 @@ err_domain = 无效的域 err_hostname = 获取主机名失败 + err_mlock = 锁定密码存储器失败 err_null = 空指针 diff --git a/src/config/Config.zig b/src/config/Config.zig index a952be8..05a14df 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -57,6 +57,8 @@ hide_borders: bool = false, hide_key_hints: bool = false, hide_keyboard_locks: bool = false, hide_version_string: bool = false, +inactivity_cmd: ?[]const u8 = null, +inactivity_delay: u16 = 0, initial_info_text: ?[]const u8 = null, input_len: u8 = 34, lang: []const u8 = "en", diff --git a/src/config/Lang.zig b/src/config/Lang.zig index 4134933..79145e5 100644 --- a/src/config/Lang.zig +++ b/src/config/Lang.zig @@ -24,6 +24,7 @@ err_envlist: []const u8 = "failed to get envlist", err_get_active_tty: []const u8 = "failed to get active tty", err_hibernate: []const u8 = "failed to execute hibernate command", err_hostname: []const u8 = "failed to get hostname", +err_inactivity: []const u8 = "failed to execute inactivity command", err_lock_state: []const u8 = "failed to get lock state", err_log: []const u8 = "failed to open log file", err_mlock: []const u8 = "failed to lock password memory", diff --git a/src/main.zig b/src/main.zig index 7addd74..fe85067 100644 --- a/src/main.zig +++ b/src/main.zig @@ -98,7 +98,7 @@ pub fn main() !void { defer _ = gpa.deinit(); // Allows stopping an animation after some time - const time_start = try interop.getTimeOfDay(); + const animation_time_start = try interop.getTimeOfDay(); var animation_timed_out: bool = false; const allocator = gpa.allocator(); @@ -284,12 +284,12 @@ pub fn main() !void { commands_allocated = true; if (config.start_cmd) |start_cmd| { - var sleep = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", start_cmd }, allocator); - sleep.stdout_behavior = .Ignore; - sleep.stderr_behavior = .Ignore; + var start = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", start_cmd }, allocator); + start.stdout_behavior = .Ignore; + start.stderr_behavior = .Ignore; handle_start_cmd: { - const process_result = sleep.spawnAndWait() catch { + const process_result = start.spawnAndWait() catch { break :handle_start_cmd; }; start_cmd_exit_code = process_result.Exited; @@ -594,6 +594,8 @@ pub fn main() !void { var update = true; var resolution_changed = false; var auth_fails: u64 = 0; + var inactivity_time_start = try interop.getTimeOfDay(); + var inactivity_cmd_ran = false; // Switch to selected TTY const active_tty = interop.getActiveTty(allocator) catch |err| no_tty_found: { @@ -858,7 +860,7 @@ pub fn main() !void { // Check how long we've been running so we can turn off the animation const time = try interop.getTimeOfDay(); - if (config.animation_timeout_sec > 0 and time.seconds - time_start.seconds > config.animation_timeout_sec) { + if (config.animation_timeout_sec > 0 and time.seconds - animation_time_start.seconds > config.animation_timeout_sec) { animation_timed_out = true; animation.deinit(); } @@ -872,6 +874,28 @@ pub fn main() !void { timeout = @intCast(1000 - @divTrunc(time.microseconds, 1000) + 1); } + if (config.inactivity_cmd) |inactivity_cmd| { + const time = try interop.getTimeOfDay(); + + if (!inactivity_cmd_ran and time.seconds - inactivity_time_start.seconds > config.inactivity_delay) { + var inactivity = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", inactivity_cmd }, allocator); + inactivity.stdout_behavior = .Ignore; + inactivity.stderr_behavior = .Ignore; + + handle_inactivity_cmd: { + const process_result = inactivity.spawnAndWait() catch { + break :handle_inactivity_cmd; + }; + if (process_result.Exited != 0) { + try info_line.addMessage(lang.err_inactivity, config.error_bg, config.error_fg); + try log_writer.print("failed to execute inactivity command: exit code {d}\n", .{process_result.Exited}); + } + } + + inactivity_cmd_ran = true; + } + } + // Skip event polling if autologin is set, use simulated Enter key press instead if (is_autologin) { event = termbox.tb_event{ @@ -892,6 +916,9 @@ pub fn main() !void { if (event_error < 0 or event.type != termbox.TB_EVENT_KEY) continue; } + // Input of some kind was detected, so reset the inactivity timer + inactivity_time_start = try interop.getTimeOfDay(); + switch (event.key) { termbox.TB_KEY_ESC => { if (config.vi_mode and insert_mode) {