#!/usr/bin/bash # vim:ft=sh:fdm=marker:fmr={,} # archlabs installer library script file # this file is not meant to be run directly # sourcing this file in a non bash shell is not advised # shellcheck disable=2154 # set -n chrun() { arch-chroot $MNT /bin/bash -c "$1" } json() { curl -s "http://api.ipstack.com/$2" | python3 -c "import sys, json; print(json.load(sys.stdin)['$1'])" } src() { . "$1" || { printf "\nFailed to source file %s\n" "$1"; die 1; } } ssd() { local dev=$1 dev=${dev#/dev/} [[ $dev =~ nvme ]] && dev=${dev%p[0-9]*} || dev=${dev%[0-9]*} [[ $(cat /sys/block/$dev/queue/rotational) -eq 0 ]] || return 1 } die() { tput cnorm if [[ -d $MNT ]] && cd; then fuser -km $MNT unmount_install_partitions if ! [[ $1 =~ [0-9] ]]; then fuser -km /run/archiso/bootmnt umount -l /run/archiso/bootmnt fi fi [[ $1 =~ [0-9] ]] && exit $1 || $1 } sigint() { printf "\n** CTRL-C caught" die 1 } msgbox() { tput civis dialog --cr-wrap --backtitle "$BT" --title " $1 " --msgbox "$2\n" 0 0 } oneshot() { [[ -e /tmp/.ai_$1 || ! $(type $1) ]] && return 0 $1 || return 1 touch "/tmp/.ai_$1" return 0 } getinput() { local answer if ! answer="$(dialog --cr-wrap --max-input 63 --stdout --no-cancel \ --backtitle "$BT" --title " $1 " --inputbox "$2" 0 0 "$3")" || [[ $answer == '' ]]; then return 1 fi printf "%s" "$answer" } infobox() { local sec="$3" tput civis dialog --cr-wrap --backtitle "$BT" --title " $1 " --infobox "$2\n" 0 0 sleep ${sec:-2} } printq() { local str="$*" if [[ ${#str} -gt $(( ${COLUMNS:-$(tput cols)} / 2 )) ]]; then q=$(awk '{print int(NF / 4)}' <<< "$str") str="$(awk '{ pkgs1=pkgs2=pkgs3=pkgs4="" for (i=1;i<'"$q"';i++) { if (i == 1) { pkgs1=$i } else { pkgs1=pkgs1" "$i } } for (i='"$q"';i<'"$((q * 2))"';i++) { pkgs2=pkgs2" "$i } for (i='"$((q * 2))"';i<'"$((q * 3))"';i++) { pkgs3=pkgs3" "$i } for (i='"$((q * 3))"';i/dev/null 2>&1; then tput civis; nmtui-connect if curl -s --head 'https://www.archlinux.org/mirrorlist/all/' | head -n 1 | grep -q '200'; then export HAS_NETWORK=true else infobox "$_ErrTitle" "$_NoNetwork" 3 fi fi fi return 0 } echeck() { # return if the last process exited normally local last_exit_code=$? (( last_exit_code == 0 )) && return 0 local msg="\nThe command exited abnormally: $1" # get error message from logfile and strip any non-printable characters, # escape sequences, and other messy text local err err="$(sed 's/[^[:print:]]//g; s/\[[0-9\;:]*\?m//g; s/==> //g; s/] ERROR:/]\nERROR:/g' "$ERR")" [[ $err != "" ]] && msgbox "$_ErrTitle" "$msg\n\nWith the following error message:\n\n$err" msg="$([[ $err == "" ]] && printf "%s" "$msg")\n$_ErrChoice" if [[ -e /tmp/debug-log && $TERM == 'linux' ]]; then msg="$([[ $err == "" ]] && printf "%s" "$msg")\n$_ErrChoiceConsole" yesno "$_ErrTitle" "$msg" "Exit & Open Log" "Ignore & Continue" && { more /tmp/debug-log; die 0; } else yesno "$_ErrTitle" "$msg" "Exit & Shutdown" "Ignore & Continue" && die 'shutdown -h now' fi return 0 } icheck() { [[ $(lsblk -o MOUNTPOINT) =~ $MNT ]] || { msgbox "$_ErrTitle" "$_ErrNoMount"; export SELECTED=4; return 1; } [[ $CONFIG_DONE == true ]] || { msgbox "$_ErrTitle" "$_ErrNoConfig"; export SELECTED=5; return 1; } return 0 } yesno() { # usage: yesno <text> [<yes_label> <no_label> [<no>]] # three options: one --default-no and custom labels, one just custom labels, and one basic. tput civis if [[ $# -eq 5 && $5 == "no" ]]; then dialog --cr-wrap --backtitle "$BT" --defaultno --title " $1 " \ --yes-label "$3" --no-label "$4" --yesno "$2\n" 0 0 elif [[ $# -eq 4 ]]; then dialog --cr-wrap --backtitle "$BT" --title " $1 " --yes-label "$3" \ --no-label "$4" --yesno "$2\n" 0 0 else dialog --cr-wrap --backtitle "$BT" --title " $1 " --yesno "$2\n" 0 0 fi } debug() { set -x exec 3>| /tmp/debug-log BASH_XTRACEFD=3 if [[ $DISPLAY && $TERM != 'linux' ]]; then if hash 'termite' >/dev/null 2>&1; then termite -e "tail -f /tmp/debug-log" & else xterm -e "tail -f /tmp/debug-log" & fi fi export DEBUG=true }