diff --git a/initrd/etc/gui_functions b/initrd/etc/gui_functions index f636e5912..cd5758223 100755 --- a/initrd/etc/gui_functions +++ b/initrd/etc/gui_functions @@ -5,10 +5,48 @@ # Pause for the configured timeout before booting automatically. Returns 0 to # continue with automatic boot, nonzero if user interrupted. pause_automatic_boot() { - if IFS= read -t "$CONFIG_AUTO_BOOT_TIMEOUT" -s -n 1 -r -p \ - $'Automatic boot in '"$CONFIG_AUTO_BOOT_TIMEOUT"$' seconds unless interrupted by keypress...\n'; then - return 1 # Interrupt automatic boot - fi + local remaining="$CONFIG_AUTO_BOOT_TIMEOUT" + + echo "Automatic boot in $CONFIG_AUTO_BOOT_TIMEOUT seconds unless interrupted by keypress..." + printf "\n" # Reserve space for the updating line + + while [ $remaining -gt 0 ]; do + # Record the start time of this loop iteration (epoch seconds) + local loop_start now_str status_line elapsed sleep_time + loop_start=$(date +%s) + + now_str=$(date -u '+%Y-%m-%d %H:%M:%S UTC') + status_line="$now_str | Booting in $remaining seconds..." + + if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TOTP_SKIP_QRCODE" != "y" ]; then + # Get current TOTP if available and not skipped + local current_totp + if ! current_totp=$(unseal-totp 2>/dev/null); then + die "Failed to unseal TOTP" + fi + status_line="$status_line | TOTP: $current_totp" + fi + + # Update the status line in place (overwrites previous output) + printf "\r%s" "$status_line" + + # Calculate elapsed time for this loop iteration + elapsed=$(( $(date +%s) - loop_start )) + # Calculate how much time to wait to complete 1 second + sleep_time=$(( 1 - elapsed )) + [ $sleep_time -lt 0 ] && sleep_time=0 + + # Wait for keypress for the remaining time in this second + # IFS= disables word splitting, -t sets timeout, -s disables echo, -n 1 reads one char, -r disables backslash escapes + if IFS= read -t $sleep_time -s -n 1 -r; then + printf "\n" # New line after interrupt + return 1 # Interrupt automatic boot + fi + + remaining=$((remaining - 1)) + done + + printf "\n" # New line after countdown return 0 # Continue with automatic boot }