From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding:content-language; bh=cMIkEUIgAQKg3ZraTMdK1qaJuBK+kJ2CjAIHQMZ/c4w=; b=U9acqHs/KRZV9POY4BF2A9JhnO3zH8WOso15xH0n7nx5lmY1aN/TQupgOOzbRo4eCb XK3Av2N9I8ZCZViJOsR0sTqZJ1XkjCwPo5g1URfIJ6xTXLCpt3uJz9cB1eevoffL8xse /u1fkRp/JmXNXOPvav6fUb3J7IWlSy4DA85FOXXbWZiliYw9EJe2Xm24KxZW6UakpyW4 gBdU2OeBB2Phv+QYMVZpZiZdQBrGYlEsXGfS1kwQiAVPktz3P7SKRMHYGKVTJ1mnDEj1 deM9g7YjhNUf8lhqIV9ZLGvqzHY9GEmQJfmPp3LGsn2VJ4ILGRjE+3DAHZqbFRLohCJS G0YQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=cMIkEUIgAQKg3ZraTMdK1qaJuBK+kJ2CjAIHQMZ/c4w=; b=BNtNhRVn4YHyebBKhNjDQbByxwsmBcvW0orVc4oFQ+RP49In6sBH8FMzm0KqZAMSIn l3ANI5LTQYWQPmaO5jMlhmmwgzsttR+Use9jSIRBO8DReBYUbL1kKDMUs7rZoFKWjtZX ME+NPmKV7KqA96zs0wvFlmg+Z6mjGOJRRHL+cgwfY+ZTnqCCknjEWcRGRu7dQrH4KMW/ srzzWq/SnOFE7TPAC3/2q0yr9CP05ulRNnSzMuqcSkAFtdug2q64VLmnSoBAWV0Sx0n6 TJc1Rv5bY99Ev8IG/sGLcQB7f+Pcl/MazClJlJGC7xmNgksfgARa8lrXsxeW5CeNUqQx RfMQ== X-Gm-Message-State: AOAM531FiPKMiDLqDtTl57yO6wVEHPdOagV5aYlBhXTPhPflPLcOko94 Xr673bi9P8VvU4un4bvdOzdKUD6OJS8= X-Google-Smtp-Source: ABdhPJzb7ulDh6aPUi1HQum7y3IiGfrZWAwIRi3R12eNjqS5C6HYDnGus75F4j9eHRtF4jV4ntYtIA== X-Received: by 2002:a2e:81c6:: with SMTP id s6mr28653897ljg.469.1635278859204; Tue, 26 Oct 2021 13:07:39 -0700 (PDT) To: make-initrd@lists.altlinux.org References: <20211024172254.5CD94A5E20@lists.altlinux.org> <20211026190344.b37x6zbhevrw72xo@example.org> From: Leonid Krivoshein Message-ID: Date: Tue, 26 Oct 2021 23:07:38 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: <20211026190344.b37x6zbhevrw72xo@example.org> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: ru Subject: Re: [make-initrd] [PATCH v6 18/22] bootchain-interactive: initial feature X-BeenThere: make-initrd@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: make-initrd@lists.altlinux.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Oct 2021 20:07:43 -0000 Archived-At: List-Archive: 26.10.2021 22:03, Alexey Gladkov пишет: > On Sun, Oct 24, 2021 at 08:22:54PM +0300, Leonid Krivoshein wrote: >> This feature adds the ability to use text dialogs in >> the initramfs scripts. See README.md for more details. > Я не понимаю, как эта фича будет работать с остальными. Например с luks > или fsck, которая может захотеть что-нибудь спросить и которая ничего из > этого не использует. Ты же не останавливаешь очень udev в ueventd. Поэтому > может вылезти любой диалог. На текущий момент bootchain-interactive можно использовать какой-то одной фичей make-initrd, например, модулями bootchain. Именно по этой причине префикс bootchain пришлось пока оставить. Очень хотелось бы эту ситуацию изменить, перетащить фичу на уровень выше, сделать её расшаренной между остальными фичами. Мы хотели обсудить воочию именно этот вопрос с тобой и Антоном. Если бы я знал, как это сделать, я бы давно сделал. Потом, я уже говорил: эта "библиотека виджетов", равно как и вся концепция "IM", была сделана наспех только ради того, чтобы было просто и удобно рисовать виджеты в altboot. Тут есть что обсуждать и, наверное, переделывать в плане улучшения. >> Signed-off-by: Leonid Krivoshein >> --- >> features/bootchain-interactive/README.md | 184 +++++++++++++ >> features/bootchain-interactive/config.mk | 5 + >> .../data/bin/activate-interactive-vt | 27 ++ >> .../data/bin/interactive-sh-functions | 247 ++++++++++++++++++ >> .../initrd/cmdline.d/bootchain-interactive | 3 + >> .../data/lib/IM-widgets/choice | 60 +++++ >> .../data/lib/IM-widgets/dlgmsg | 25 ++ >> .../data/lib/IM-widgets/errmsg | 29 ++ >> .../data/lib/IM-widgets/form | 70 +++++ >> .../data/lib/IM-widgets/gauge | 31 +++ >> .../data/lib/IM-widgets/ponder | 67 +++++ >> features/bootchain-interactive/rules.mk | 2 + >> 12 files changed, 750 insertions(+) >> create mode 100644 features/bootchain-interactive/README.md >> create mode 100644 features/bootchain-interactive/config.mk >> create mode 100755 features/bootchain-interactive/data/bin/activate-interactive-vt >> create mode 100644 features/bootchain-interactive/data/bin/interactive-sh-functions >> create mode 100644 features/bootchain-interactive/data/etc/initrd/cmdline.d/bootchain-interactive >> create mode 100644 features/bootchain-interactive/data/lib/IM-widgets/choice >> create mode 100644 features/bootchain-interactive/data/lib/IM-widgets/dlgmsg >> create mode 100644 features/bootchain-interactive/data/lib/IM-widgets/errmsg >> create mode 100644 features/bootchain-interactive/data/lib/IM-widgets/form >> create mode 100644 features/bootchain-interactive/data/lib/IM-widgets/gauge >> create mode 100644 features/bootchain-interactive/data/lib/IM-widgets/ponder >> create mode 100644 features/bootchain-interactive/rules.mk >> >> diff --git a/features/bootchain-interactive/README.md b/features/bootchain-interactive/README.md >> new file mode 100644 >> index 0000000..adb3de5 >> --- /dev/null >> +++ b/features/bootchain-interactive/README.md >> @@ -0,0 +1,184 @@ >> +# Feature: bootchain-interactive >> + >> +Feature adds the ability to use text dialogs in the initramfs scripts. >> + >> +## Boot parameters >> + >> +- `console=...` - Disable to switch TTY's, it useful for network/serial console. >> +- `noaskuser` - Disable all dialogs, it useful for console without user. >> +- `nolines` - Disable pseudo-graphics line drawing, it useful if not supported. >> + >> +## Synopsis >> +``` >> +. interactive-sh-functions >> +``` >> + >> +## Global variables >> + >> +- `$IM_BACKTITLE` - Back title for all input and output dialogs. >> +- `$IM_WIDGET_ARGS` - Additional arguments for `dialog` command. >> +- `$CONSOLE` - Non-empty value, if switching between TTY's are disabled. >> +- `$NOASKUSER` - Non-empty value, if all dialogs are disabled. >> +- `$NOLINES` - Non-empty value, if pseudo-graphics line drawing are disabled. >> + >> +## Briefly API >> + >> +- `IM_is_active()` - Returns 0, if interactive mode already activated. >> +- `IM_exec()` - Re-execute specified process on the foreground (tty2 by >> + default). >> +- `IM_activate()` - Request to immediately or delayed activation of the >> + interactive mode. >> +- `IM_load_widgets()` - Load specified widgets from the library. >> +- `IM_load_all()` - Load all available widgets from the library. >> +- `IM_start_output()` - Notify `interactive` feature about starting output. >> +- `IM_start_input()` - Notify `interactive` feature about starting intput. >> +- `IM_show_bootsplash()` - Show bootsplash such as plymoth and start the >> + progress bar. >> +- `IM_hide_bootsplash()` - Hide bootsplash such as plymoth and stop the >> + progress bar. >> +- `IM_update_bootsplash()` - Notify bootsplash such as plymoth about boot >> + state changes. >> + >> +## Widgets library >> + >> +Library is a scripts set, located in /lib/IM-widgets directory inside intitramfs >> +iamge. The base set can be extended. Before use input widgets, `IM_start_input()` >> +must be called, and `IM_start_output()` in otherwise. >> + >> +### choice (input) >> + >> +Display menu with one or more items, labels before items not displayed. >> +On success returns 0 and write choosen label to specified variable. Based >> +on `dialog --menu`. >> + >> +Syntax: >> +``` >> +IM_choice [ ???] >> +``` >> + >> +Example: >> +``` >> +text="Please choose the installation method." >> + >> +while ! IM_choice method "$text" \ >> + nfs "NFS server" \ >> + ftp "FTP server" \ >> + http "HTTP server" \ >> + cifs "SAMBA server" \ >> + cdrom "CD-ROM Drive" \ >> + disk "Hard Disk Drive" \ >> + # >> +do >> + sleep 0.5 >> +done >> + >> +case "$method" in >> +nfs) >> +??? >> +esac >> +``` >> + >> +### dlgmsg (input) >> + >> +Display text message. Always returns 0. Based on `dialog --msgbox`. >> + >> +Syntax: >> +``` >> +IM_dlgmsg <text> >> +``` >> + >> +Example: >> +``` >> +IM_dlgmsg "Live is success!" "$text" >> +``` >> + >> +### errmsg (input) >> + >> +Display error message. Always returns 0. Based on `dialog --msgbox`. >> + >> +Syntax: >> +``` >> +IM_errmsg <text> >> +``` >> + >> +Example: >> +``` >> +IM_errmsg "Disk read error, try again!" >> +``` >> + >> +### form (input) >> + >> +Display mixed data form. Input one or more text fields and store values >> +to specified varibales. Some variables associated with private data, >> +such as password, this input field characters outputs as asterics (`*`). >> +On success returns 0 and fill all variables by the entered values. >> +Based on `dialog --mixedform`. >> + >> +Syntax: >> +``` >> +IM_form <title> <text> <text-height> \ >> + <varname1> <fldlen1> <caption1> \ >> + [<varname2> <fldlen2> <caption2>???] >> +``` >> + >> +Example: >> +``` >> +IM_form "$title" "$text" 5 \ >> + server 64 "HTTP-server" \ >> + directory 128 "Directory" \ >> + || >> + continue >> +[ -n "$server" ] && [ -n "$directory" ] || >> + continue >> +``` >> + >> +### gauge (output) >> + >> +Display gauge (progress bar). Integer value from 0 to 100 must be sent >> +via stdin to specify displayed percent of the process passed. This is work >> +in conjuction with pv command. Always returns 0. Based on `dialog --gauge`. >> + >> +Note for `netconsole` usage: after process will finish, don't forget reset >> +the terminal, otherwise keyboard input will be lost. >> + >> +Syntax: >> +``` >> +echo <integer> | IM_gauge <title> [<text>] >> +``` >> + >> +Example: >> +``` >> +( for i in $(seq 1 10); do >> + echo "${i}0" >> + sleep 1 >> + done >> +) | IM_gauge "[ Loading... ]" >> + >> +[ -z "$CONSOLE" ] || >> + reset >> +``` >> + >> +### ponder (output) >> + >> +Displays the <waiting???> widget, which displays the undefined time of the >> +ongoing process, works independently of the main program code. The parameters >> +<delay> and <step> at startup determine by how many percent the thermometer >> +will automatically advance after a given time, i.e. set the frequency and >> +speed of the widget refresh. Always returns 0. Based on the `gauge` widget. >> + >> +Syntax: >> +``` >> +IM_ponder_start <title> [[[<text>] <delay>] <step>] >> +??? >> +IM_ponder_stop >> +``` >> + >> +Example: >> +``` >> +IM_ponder_start "[ Scanning disk... ]" \ >> + "Searching random bits on the disk for fill CRNG entropy..." >> +find / -type f -print0 | >> + xargs -0 grep "Linus Torvalds" >/tmp/Linus.txt 2>/dev/null >> +rm -f /tmp/Linus.txt >> +IM_ponder_stop >> +``` >> diff --git a/features/bootchain-interactive/config.mk b/features/bootchain-interactive/config.mk >> new file mode 100644 >> index 0000000..69c8756 >> --- /dev/null >> +++ b/features/bootchain-interactive/config.mk >> @@ -0,0 +1,5 @@ >> +$(call feature-requires,depmod-image) >> + >> +BOOTCHAIN_INTERACTIVE_DATADIR = $(FEATURESDIR)/bootchain-interactive/data >> + >> +BOOTCHAIN_INTERACTIVE_PROGS = chvt dialog openvt pv >> diff --git a/features/bootchain-interactive/data/bin/activate-interactive-vt b/features/bootchain-interactive/data/bin/activate-interactive-vt >> new file mode 100755 >> index 0000000..90ae329 >> --- /dev/null >> +++ b/features/bootchain-interactive/data/bin/activate-interactive-vt >> @@ -0,0 +1,27 @@ >> +#!/bin/bash -efu >> + >> +. interactive-sh-functions >> + >> +delay="${1-}" >> + >> +IM_is_active || >> + fatal "interactive mode required" >> +exec </dev/null >/dev/null 2>&1 >> + >> +if [ -n "$delay" ]; then >> + while [ ! -f "${_IM_activated}" ]; do >> + [ "$delay" -gt 0 ] || >> + break >> + delay=$(( $delay - 1 )) >> + sleep 1 >> + done >> + sleep 1 >> +fi >> + >> +if [ ! -f "${_IM_activated}" ] && IM_is_active; then >> + :> "${_IM_activated}" >> + IM_hide_bootsplash >> + [ -n "$CONSOLE" ] || >> + chvt "${_IM_VT_number}" >> + rootdelay_pause >> +fi >> diff --git a/features/bootchain-interactive/data/bin/interactive-sh-functions b/features/bootchain-interactive/data/bin/interactive-sh-functions >> new file mode 100644 >> index 0000000..9baf3df >> --- /dev/null >> +++ b/features/bootchain-interactive/data/bin/interactive-sh-functions >> @@ -0,0 +1,247 @@ >> +#!/bin/bash -efu >> + >> +if [ -z "${__interactive_sh_functions-}" ]; then >> +__interactive_sh_functions=1 >> + >> +. /.initrd/initenv >> +. initrd-sh-functions >> + >> +. shell-signal >> + >> +message_time=1 >> + >> +# Public >> +IM_BACKTITLE= >> +IM_WIDGET_ARGS= >> +CONSOLE="${CONSOLE-}" >> +NOASKUSER="${NOASKUSER-}" >> +NOLINES="${NOLINES-}" >> + >> +# Internal >> +_IM_max_width= >> +_IM_widgetsdir=/lib/IM-widgets >> +_IM_flag=/.initrd/interactive-mode >> +_IM_unsplashed="${_IM_flag}/BOOTSPLASH-STOPPED" >> +_IM_activated="${_IM_flag}/VT-ACTIVATED" >> +_IM_VT_number="${_IM_VT_number:-2}" >> + >> +# Standart "reboot message" >> +IM_RBMSG="Press ENTER to reboot the computer..." >> + >> + >> +IM_is_active() >> +{ >> + [ -d "${_IM_flag}" ] || >> + return 1 >> +} >> + >> +IM_ponder_stop() >> +{ >> + : # Base implementation overrided in /lib/IM-widgets/ponder >> +} >> + >> +_IM_exit_handler() >> +{ >> + local rc=$? >> + >> + trap - EXIT >> + >> + if IM_is_active; then >> + IM_ponder_stop >> + rootdelay_unpause >> + if [ -z "$CONSOLE" ] && [ -z "$NOASKUSER" ]; then >> + clear >> + chvt 1 >> + fi >> + IM_show_bootsplash >> + rm -rf -- "${_IM_flag}" >> + fi >> + >> + exit $rc >> +} >> + >> +IM_exec() >> +{ >> + local now= >> + >> + if [ "${1-}" = "--now" ]; then >> + now=-s >> + shift >> + fi >> + >> + ! IM_is_active || >> + fatal "already in interactive mode" >> + >> + if [ -n "$CONSOLE" ] || [ -n "$NOASKUSER" ]; then >> + exec "$@" >> + else >> + [ -e "/dev/tty${_IM_VT_number}" ] || >> + mknod "/dev/tty${_IM_VT_number}" c 4 ${_IM_VT_number} >> + exec openvt -f -w $now -c${_IM_VT_number} -- "$@" >> + fi >> + >> + fatal "exec failed in IM_exec()" >> +} >> + >> +# shellcheck disable=SC2120 >> +IM_activate() >> +{ >> + local delay="${1-}" >> + local logfile="${2:-/var/log/IM.log}" >> + >> + ! IM_is_active || >> + fatal "already in interactive mode" >> + set_cleanup_handler _IM_exit_handler >> + >> + if [ -n "$NOASKUSER" ]; then >> + exec </dev/null >/dev/null 2>>"$logfile" >> + elif [ -n "$CONSOLE" ]; then >> + exec </dev/console >/dev/console 2>>"$logfile" >> + else >> + exec <"/dev/tty${_IM_VT_number}" >"/dev/tty${_IM_VT_number}" 2>>"$logfile" >> + fi >> + >> + mkdir -p -- "${_IM_flag}" >> + >> + export TERM="${TERM:-linux}" >> + export DIALOG_TTY=1 >> + export LC_ALL=C >> + export LANG=C >> + >> + # Determinating maximum width >> + if [ -n "$NOASKUSER" ]; then >> + _IM_max_width=80 >> + printf '%s\n' "${_IM_max_width}" >"${_IM_flag}/MAX-WIDTH" >> + elif [ -z "${_IM_max_width}" ]; then >> + local esc cols rows >> + >> + # The snippet above by Oleg Nesterov (C) was modified for IM, see: >> + # https://lists.altlinux.org/pipermail/make-initrd/2021-June/000458.html >> + # >> + echo -ne "\e[s\e[1000;1000H\e[6n\e[u" >> + # shellcheck disable=SC2162 >> + IFS=';[' read -s -t2 -dR esc rows cols || { >> + rows=24 >> + cols=80 >> + } >> + _IM_max_width=$(( $cols - 6 )) >> + stty rows "$rows" cols "$cols" 2>/dev/null ||: >> + printf '%s\n' "${_IM_max_width}" >"${_IM_flag}/MAX-WIDTH" >> + fi >> + >> + # Activating IM VT >> + if [ -n "$NOASKUSER" ]; then >> + message "TTY's not used, dialogs are disabled" >> + elif [ -n "$CONSOLE" ]; then >> + activate-interactive-vt >> + message "TTY's not available, using current system console" >> + elif [ -z "$delay" ]; then >> + activate-interactive-vt >> + message "TTY${_IM_VT_number} now active" >> + else >> + activate-interactive-vt "$delay" & >> + message "TTY${_IM_VT_number} will be activated after $((1 + $delay)) seconds" >> + fi >> + >> + # Warm up: back title do not displayed only with the first widget >> + # after openvt(), single dialog exec strangely solve this problem. >> + # >> + if [ -z "$CONSOLE" ] && [ -z "$NOASKUSER" ]; then >> + dialog ${NOLINES:+--ascii-lines} \ >> + --backtitle "WARM UP" \ >> + --title "[ Loading widgets ]" \ >> + --pause "" 7 40 0 \ >> + ||: >> + fi >> + >> + # Also we need to load and to check all widgets before using them >> + IM_load_all >> +} >> + >> +IM_load_widgets() >> +{ >> + local widget loaded >> + >> + for widget in "$@" _; do >> + [ -s "${_IM_widgetsdir}/$widget" ] || >> + continue >> + eval "loaded=\"\${__IM_${widget}_loaded-}\"" >> + >> + if [ -z "$loaded" ]; then >> + eval "__IM_${widget}_loaded=1" >> + . "${_IM_widgetsdir}/$widget" >> + fi >> + done >> +} >> + >> +IM_load_all() >> +{ >> + local widget >> + >> + # shellcheck disable=SC2045 >> + for widget in $(ls -- "${_IM_widgetsdir}/"); do >> + IM_load_widgets "$widget" >> + done >> +} >> + >> +IM_start_output() >> +{ >> + # shellcheck disable=SC2119 >> + IM_is_active || >> + IM_activate >> + [ -n "${_IM_max_width}" ] || >> + read -r _IM_max_width <"${_IM_flag}/MAX-WIDTH" || >> + _IM_max_width=66 >> + IM_load_widgets "$@" >> +} >> + >> +IM_start_input() >> +{ >> + [ -z "$NOASKUSER" ] || >> + fatal "input widgets not allowed, dialogs are disabled" >> + IM_start_output "$@" >> + [ -f "${_IM_activated}" ] || >> + activate-interactive-vt >> +} >> + >> +IM_show_bootsplash() >> +{ >> + local cmd=plymouth >> + >> + if IM_is_active && >> + [ -f "${_IM_unsplashed}" ] && >> + command -v $cmd >/dev/null && >> + $cmd --ping >/dev/null 2>&1 >> + then >> + $cmd unpause-progress --show-splash ||: >> + rm -f -- "${_IM_unsplashed}" >> + fi >> +} >> + >> +IM_hide_bootsplash() >> +{ >> + local cmd=plymouth >> + >> + if IM_is_active && >> + [ ! -f "${_IM_unsplashed}" ] && >> + command -v $cmd >/dev/null && >> + $cmd --ping >/dev/null 2>&1 >> + then >> + $cmd pause-progress --hide-splash ||: >> + :> "${_IM_unsplashed}" >> + fi >> +} >> + >> +IM_update_bootsplash() >> +{ >> + local cmd=plymouth >> + >> + if IM_is_active && >> + command -v $cmd >/dev/null && >> + $cmd --ping >/dev/null 2>&1 >> + then >> + $cmd update --status="$1" ||: >> + fi >> +} >> + >> +fi # __interactive_sh_functions >> diff --git a/features/bootchain-interactive/data/etc/initrd/cmdline.d/bootchain-interactive b/features/bootchain-interactive/data/etc/initrd/cmdline.d/bootchain-interactive >> new file mode 100644 >> index 0000000..8676770 >> --- /dev/null >> +++ b/features/bootchain-interactive/data/etc/initrd/cmdline.d/bootchain-interactive >> @@ -0,0 +1,3 @@ >> +register_parameter string CONSOLE >> +register_parameter bool NOASKUSER >> +register_parameter bool NOLINES >> diff --git a/features/bootchain-interactive/data/lib/IM-widgets/choice b/features/bootchain-interactive/data/lib/IM-widgets/choice >> new file mode 100644 >> index 0000000..23517e0 >> --- /dev/null >> +++ b/features/bootchain-interactive/data/lib/IM-widgets/choice >> @@ -0,0 +1,60 @@ >> +#!/bin/bash -efu >> + >> +IM_choice() >> +{ >> + IM_start_input >> + >> + local varname="$1" text="${2:-\n}"; shift 2 >> + local height=1 width=$(( 4 + ${#text} )) >> + local rc=0 items=$(( $# / 2 )) >> + >> + _calculate_items_width() >> + { >> + local label iw i=0 >> + >> + while [ $i -lt $items ]; do >> + label="$2"; shift 2 >> + iw=$(( 4 + ${#label} )) >> + [ $iw -le $width ] || >> + width=$iw >> + i=$((1 + $i)) >> + done >> + } >> + >> + [ $items -gt 0 ] || >> + return 1 >> + [ $width -gt "${_IM_max_width}" ] || >> + _calculate_items_width "$@" >> + if [ $width -lt 40 ]; then >> + width=40 >> + elif [ $width -gt ${_IM_max_width} ]; then >> + height=$(( $width / ${_IM_max_width} + 1 )) >> + width=${_IM_max_width} >> + fi >> + if [ $items -gt 7 ]; then >> + height=$((14 + $height)) >> + else >> + height=$((7 + $height + $items)) >> + fi >> + >> + local dlgcmd="dialog $IM_WIDGET_ARGS ${NOLINES:+--ascii-lines}" >> + dlgcmd="$dlgcmd ${IM_BACKTITLE:+--backtitle \"$IM_BACKTITLE\"}" >> + dlgcmd="$dlgcmd --title \"[ Please choose... ]\"" >> + dlgcmd="$dlgcmd --no-tags --menu \"\n$text\"" >> + dlgcmd="$dlgcmd $height $width $items" >> + >> + while [ $# -ge 2 ]; do >> + dlgcmd="$dlgcmd \"$1\" \"$2\"" >> + shift 2 >> + done >> + >> + exec 3>&1 >> + text="$(eval "$dlgcmd" 2>&1 1>&3)" || rc=$? >> + exec 3>&- >> + >> + [ -z "$CONSOLE" ] || >> + reset >> + [ $rc -eq 0 ] || >> + return $rc >> + eval "$varname=\"$text\"" >> +} >> diff --git a/features/bootchain-interactive/data/lib/IM-widgets/dlgmsg b/features/bootchain-interactive/data/lib/IM-widgets/dlgmsg >> new file mode 100644 >> index 0000000..74e1eba >> --- /dev/null >> +++ b/features/bootchain-interactive/data/lib/IM-widgets/dlgmsg >> @@ -0,0 +1,25 @@ >> +#!/bin/bash -efu >> + >> +IM_dlgmsg() >> +{ >> + IM_start_input >> + >> + local title="$1" text="$2" height=2 >> + local width=$(( 4 + ${#text} )) >> + >> + if [ $width -lt 40 ]; then >> + width=40 >> + elif [ $width -gt ${_IM_max_width} ]; then >> + height=$(( $width / ${_IM_max_width} + 2 )) >> + width=${_IM_max_width} >> + fi >> + >> + dialog $IM_WIDGET_ARGS \ >> + ${NOLINES:+--ascii-lines} \ >> + ${IM_BACKTITLE:+--backtitle "$IM_BACKTITLE"} \ >> + --title "$title" \ >> + --msgbox "\n$text" \ >> + $((4 + $height)) $width ||: >> + [ -z "$CONSOLE" ] || >> + reset >> +} >> diff --git a/features/bootchain-interactive/data/lib/IM-widgets/errmsg b/features/bootchain-interactive/data/lib/IM-widgets/errmsg >> new file mode 100644 >> index 0000000..e5f05db >> --- /dev/null >> +++ b/features/bootchain-interactive/data/lib/IM-widgets/errmsg >> @@ -0,0 +1,29 @@ >> +#!/bin/bash -efu >> + >> +IM_errmsg() >> +{ >> + IM_start_input >> + >> + local text="$1" height=2 >> + local width=$(( 4 + ${#text} )) >> + >> + if [ $width -lt 40 ]; then >> + width=40 >> + elif [ $width -gt ${_IM_max_width} ]; then >> + height=$(( $width / ${_IM_max_width} + 2 )) >> + width=${_IM_max_width} >> + fi >> + >> + [ ! -s /etc/dialogrc.error ] || >> + export DIALOGRC=/etc/dialogrc.error >> + dialog $IM_WIDGET_ARGS \ >> + ${NOLINES:+--ascii-lines} \ >> + ${IM_BACKTITLE:+--backtitle "$IM_BACKTITLE"} \ >> + --title "[ Error! ]" \ >> + --msgbox "\n$text" \ >> + $((4 + $height)) $width ||: >> + [ -z "$CONSOLE" ] || >> + reset >> + [ ! -s /etc/dialogrc.error ] || >> + export DIALOGRC= >> +} >> diff --git a/features/bootchain-interactive/data/lib/IM-widgets/form b/features/bootchain-interactive/data/lib/IM-widgets/form >> new file mode 100644 >> index 0000000..0c8c98e >> --- /dev/null >> +++ b/features/bootchain-interactive/data/lib/IM-widgets/form >> @@ -0,0 +1,70 @@ >> +#!/bin/bash -efu >> + >> +IM_form() >> +{ >> + IM_start_input >> + >> + local i=0 lw=0 formHeight=$(( $# / 3 - 1 )) >> + local title="$1" text="$2" textHeight="$3" >> + local label varname ilen itype; shift 3 >> + >> + _calculate_labels_width() >> + { >> + while [ $i -lt $formHeight ]; do >> + label="$3"; shift 3 >> + [ ${#label} -le $lw ] || >> + lw=${#label} >> + i=$((1 + $i)) >> + done >> + } >> + >> + [ $formHeight -gt 0 ] || >> + return 1 >> + [ -n "$title" ] || >> + title="[ Please fill entries... ]" >> + _calculate_labels_width "$@" >> + lw=$((4 + $lw)); i=1 >> + >> + local width=60 rc=0 vars="" values="" >> + local height=$((7 + $textHeight + $formHeight)) >> + local fieldWidth=$(( $width - $lw - 6 )) >> + >> + local dlgcmd="dialog $IM_WIDGET_ARGS ${NOLINES:+--ascii-lines}" >> + dlgcmd="$dlgcmd ${IM_BACKTITLE:+--backtitle \"$IM_BACKTITLE\"}" >> + dlgcmd="$dlgcmd --insecure --title \"$title\"" >> + dlgcmd="$dlgcmd --mixedform \"\n$text\"" >> + dlgcmd="$dlgcmd $height $width $formHeight" >> + >> + while [ $i -le $formHeight ]; do >> + varname="$1" >> + ilen="$2" >> + label="$3" >> + shift 3 >> + itype=0 >> + case "$varname" in >> + password*|passwd*|pass|pass1|pass2) >> + itype=1 >> + ;; >> + esac >> + vars="${vars}${varname} " >> + dlgcmd="$dlgcmd \"$label:\" $i 1 \"\${$varname}\"" >> + dlgcmd="$dlgcmd $i $lw $fieldWidth $ilen $itype" >> + i=$((1 + $i)) >> + done >> + >> + exec 3>&1 >> + values=$(eval "$dlgcmd" 2>&1 1>&3) || rc=$? >> + exec 3>&- >> + >> + [ -z "$CONSOLE" ] || >> + reset >> + [ "$rc" = 0 ] || >> + return $rc >> + i=1 >> + while [ "$i" -le "$formHeight" ]; do >> + varname="$(echo "$vars" |cut -f$i -d ' ')" >> + rc="$(echo "$values" |sed -n -r ${i}p)" >> + eval "$varname=\"$rc\"" >> + i=$((1 + $i)) >> + done >> +} >> diff --git a/features/bootchain-interactive/data/lib/IM-widgets/gauge b/features/bootchain-interactive/data/lib/IM-widgets/gauge >> new file mode 100644 >> index 0000000..baf7ac5 >> --- /dev/null >> +++ b/features/bootchain-interactive/data/lib/IM-widgets/gauge >> @@ -0,0 +1,31 @@ >> +#!/bin/bash -efu >> + >> +IM_gauge() >> +{ >> + IM_start_output >> + >> + local title="$1" text="${2-}" >> + local height=1 width=$(( 4 + ${#text} )) >> + >> + if [ $width -gt ${_IM_max_width} ]; then >> + height=$(( $width / ${_IM_max_width} + 1 )) >> + width=${_IM_max_width} >> + elif [ $width -lt 40 ]; then >> + [ $width -ne 4 ] || >> + height=0 >> + width=40 >> + fi >> + >> + if [ -n "$text" ]; then >> + height=$((1 + $height)) >> + text="\n$text" >> + fi >> + >> + dialog $IM_WIDGET_ARGS \ >> + ${NOLINES:+--ascii-lines} \ >> + ${IM_BACKTITLE:+--backtitle "$IM_BACKTITLE"} \ >> + --title "$title" \ >> + --gauge "$text" \ >> + $((5 + $height)) $width 2>/dev/null \ >> + ||: >> +} >> diff --git a/features/bootchain-interactive/data/lib/IM-widgets/ponder b/features/bootchain-interactive/data/lib/IM-widgets/ponder >> new file mode 100644 >> index 0000000..c6d4600 >> --- /dev/null >> +++ b/features/bootchain-interactive/data/lib/IM-widgets/ponder >> @@ -0,0 +1,67 @@ >> +#!/bin/bash -efu >> + >> +# Internal >> +_IM_ponder_pid= >> +_IM_ponder_finished="${_IM_flag}/PONDER-FINISHED" >> + >> +_IM_ponder_bg() >> +{ >> + local dlgcmd="IM_gauge \"$1\" \"$2\"" >> + local delay="$3" step="$4" percent=0 forward=1 >> + >> + ( while [ ! -f "${_IM_ponder_finished}" ]; do >> + echo "$percent" >> + >> + if [ $forward -ne 0 ]; then >> + if [ $percent -lt 100 ]; then >> + percent=$(( $percent + $step )) >> + else >> + percent=$(( $percent - $step )) >> + forward=0 >> + fi >> + else >> + if [ $percent -gt 0 ]; then >> + percent=$(( $percent - $step )) >> + else >> + percent=$(( $percent + $step )) >> + forward=1 >> + fi >> + fi >> + >> + [ $percent -le 100 ] || >> + percent=100 >> + [ $percent -ge 0 ] || >> + percent=0 >> + sleep "$delay" >> + done >> + >> + echo "100" >> + ) |eval "$dlgcmd" >> +} >> + >> +IM_ponder_start() >> +{ >> + IM_start_output gauge >> + >> + local title="$1" text="${2-}" >> + local delay="${3:-0.5}" >> + local step="${4:-10}" >> + >> + [ -z "${_IM_ponder_pid}" ] || >> + return 0 >> + rm -f -- "${_IM_ponder_finished}" >> + _IM_ponder_bg "$title" "$text" "$delay" "$step" & >> + _IM_ponder_pid=$! >> +} >> + >> +IM_ponder_stop() >> +{ >> + [ -n "${_IM_ponder_pid}" ] || >> + return 0 >> + :> "${_IM_ponder_finished}" >> + wait "${_IM_ponder_pid}" 2>/dev/null ||: >> + rm -f -- "${_IM_ponder_finished}" >> + [ -z "$CONSOLE" ] || >> + reset >> + _IM_ponder_pid= >> +} >> diff --git a/features/bootchain-interactive/rules.mk b/features/bootchain-interactive/rules.mk >> new file mode 100644 >> index 0000000..b647caf >> --- /dev/null >> +++ b/features/bootchain-interactive/rules.mk >> @@ -0,0 +1,2 @@ >> +PUT_FEATURE_DIRS += $(BOOTCHAIN_INTERACTIVE_DATADIR) >> +PUT_FEATURE_PROGS += $(BOOTCHAIN_INTERACTIVE_PROGS) >> -- >> 2.24.1 >> >> _______________________________________________ >> Make-initrd mailing list >> Make-initrd@lists.altlinux.org >> https://lists.altlinux.org/mailman/listinfo/make-initrd > -- Best regards, Leonid Krivoshein.