diff --git a/lang/english.trans b/lang/english.trans
index 86ae843..6013b1c 100644
--- a/lang/english.trans
+++ b/lang/english.trans
@@ -70,14 +70,16 @@ _MirrorCmd="\nThe command below will be used to sort the mirrorlist, a short des
# window managers and packages
_WMChoice="Select WMs or DEs"
_WMChoiceBody="\nUse [Space] to (de)select window manager(s) or desktop environment(s) to install.\n\nDepending on your choice additional packages may be installed to improve the experience."
-_ExtraPackages="Extra Packages"
-_ExtraPackagesBody="\nUse [Space] to (de)select packages(s) to install from the list below.\n\nNOTE: Some packages may already be installed by your DE (if any) or added automatically depending on your choice of WM."
+
+_Packages="Install Packages"
+_PackageMenu="\nSelect a package category to choose packages from that category.\n\nWhen finished select '$_Done' to finalize choices and continue.\n\nAdditional packages can be added by simply re-visiting the menu, however removing choices will require starting from the beginning of the configure menu."
+_PackageBody="\nUse [Space] to (de)select packages(s) to install from the list below.\n\nNOTE: Some packages may already be installed by your DE (if any) or added automatically depending on your choice of WM. Additionally, extra packages may be installed to improve the experience for another choice eg. when installing qutebrowser qt5ct (the Qt5 theme tool) will also be installed."
# login setup
-_WMLogin="Select Login Type"
-_LoginTypeBody="\nSelect how you want to log in to the computer, using a display manager or xinit."
-_WMLoginBody="\nSelect which window manager or desktop to use as your primary login."
-_AutoLoginBody="\nDo you want the new user to be automatically logged in when the computer starts?"
+_WMLogin="Select Login Managment"
+_LoginTypeBody="\nSelect how you want to log in, using a display manager or xinit."
+_WMLoginBody="\nSelect which window manager or desktop to use as your primary login.\n\nThis can be changed by editing your ~/.xinitrc"
+_AutoLoginBody="\nDo you want to enable auto-login and have 'startx' run when the computer starts?"
# Set keymap, hwclock, local and timezone
_CMapTitle="Virtual Console Keymap"
diff --git a/src/archlabs-installer b/src/archlabs-installer
index 6625218..53776a7 100755
--- a/src/archlabs-installer
+++ b/src/archlabs-installer
@@ -1,582 +1,19 @@
#!/usr/bin/bash
-
-# vim:fdm=marker:fmr={,}
+# shellcheck disable=2154,2034,2153
# This program is free software, provided under the GNU GPL
# Written by Nathaniel Maia for use in Archlabs
# Some ideas and code has been taken from other installers
# AIF, Cnichi, Calamares, The Arch Wiki.. Credit where credit is due
-# set -n
-# shellcheck disable=2154,2034,2153
-
-# globals {
-
-# immutable values
-readonly VER="1.7.17" # Installer version
+# immutable globals
+readonly VER="1.7.18" # Installer version
readonly DIST="ArchLabs" # Linux distributor
readonly MNT="/mnt/install" # Install mountpoint
readonly ERR="/tmp/errlog" # Built-in error log
readonly DBG="/tmp/debuglog" # Built-in error log
-# mutable values
-declare -g WARN=false
-declare -g AUTOLOGIN=false
-declare -g CONFIG_DONE=false
-declare -g SEPERATE_BOOT=false
-declare -g HAS_NETWORK=false
-
-declare -g BT="$DIST Installer - (x86_64) - Version $VER"
-declare -g ROOT_PART=""
-declare -g BOOT_DEVICE=""
-declare -g BOOT_PART=""
-declare -g BOOTLDR=""
-declare -g EXTRA_MNT=""
-declare -g EXTRA_MNTS=""
-declare -g SWAP_PART=""
-declare -g SWAP_SIZE=""
-declare -g NEWUSER=""
-declare -g USER_PASS=""
-declare -g ROOT_PASS=""
-declare -g LOGIN_WM=""
-declare -g LOGIN_TYPE=""
-declare -g INSTALL_WMS=""
-declare -g KERNEL=""
-declare -g WM_PACKAGES=""
-declare -g PACKAGES=""
-declare -g MYSHELL=""
-declare -g MKINIT_HOOKS="shutdown"
-
-# }
-
-select_language() {
- tput civis
- local lang
- local title="\nLanguage - sprache - taal - språk - lingua - idioma - nyelv - língua\n"
- lang=$(menubox "Select Language" "$title" 0 0 0 \
- "1" "English (en_**)" "2" "Español (es_ES)" \
- "3" "Português [Brasil] (pt_BR)" "4" "Português (pt_PT)" \
- "5" "Français (fr_FR)" "6" "Russkiy (ru_RU)" \
- "7" "Italiano (it_IT)" "8" "Nederlands (nl_NL)" \
- "9" "Magyar (hu_HU)" "10" "Chinese (zh_CN)")
-
- local srcdir="/usr/share/archlabs/installer/lang"
- src $srcdir/english.trans
- FONT="ter-i16n"
-
- case $lang in
- 1) LOC="en_US.UTF-8" ;;
- 2) src $srcdir/spanish.trans && LOC="es_ES.UTF-8" ;;
- 3) src $srcdir/p_brasil.trans && LOC="pt_BR.UTF-8" ;;
- 4) src $srcdir/portuguese.trans && LOC="pt_PT.UTF-8" ;;
- 5) src $srcdir/french.trans && LOC="fr_FR.UTF-8" ;;
- 6) src $srcdir/russian.trans && LOC="ru_RU.UTF-8" FONT="LatKaCyrHeb-16" ;;
- 7) src $srcdir/italian.trans && LOC="it_IT.UTF-8" ;;
- 8) src $srcdir/dutch.trans && LOC="nl_NL.UTF-8" ;;
- 9) src $srcdir/hungarian.trans && LOC="hu_HU.UTF-8" FONT="lat2-16" ;;
- 10) src $srcdir/chinese.trans && LOC="zh_CN.UTF-8" ;;
- *) die
- esac
-
- sed -i "s/#en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen
- if [[ $LOC != "en_US.UTF-8" ]]; then
- sed -i "s/#${LOC}/${LOC}/" /etc/locale.gen
- locale-gen >/dev/null 2>&1
- fi
- [[ $TERM == 'linux' ]] && setfont $FONT >/dev/null 2>&1
- export LANG="$LOC"
- return 0
-}
-
-user_creation() {
- tput cnorm
- local values
- if ! values="$(dialog --stdout --no-cancel --separator '~' --ok-label "Submit" --backtitle "$BT" \
- --title " $_UserTitle " --insecure --mixedform "$_UserBody" 27 75 10 \
- "$_Username" 1 1 "" 1 $((${#_Username} + 2)) 71 0 0 \
- "$_Password" 2 1 "" 2 $((${#_Password} + 2)) 71 0 1 \
- "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) 71 0 1 \
- "$_RootBody" 6 1 "" 6 $((${#_RootBody} + 1)) 71 0 2 \
- "$_Password" 8 1 "" 8 $((${#_Password} + 2)) 71 0 1 \
- "$_Password2" 9 1 "" 9 $((${#_Password2} + 2)) 71 0 1 |
- openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"; then
- return 1
- fi
-
-# username doesn't need to be re-encrypted
-local user
-user="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
- awk -F'~' '{print $1}')"
-
-# all of this is a bit hacky, but we don't ever want the passwords to be stored in plain text
- # so it decrypts the string '$values', gets the field we want, and re-encrypts it
- local pass pass2
- pass="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
- awk -F'~' '{print $2}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
- pass2="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
- awk -F'~' '{print $3}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
-
- local rpass rpass2
- rpass="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
- awk -F'~' '{print $5}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
- rpass2="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
- awk -F'~' '{print $6}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
-
- # due to encrypting the string, when empty, once encrypted it wont be empty
- local empty
- empty="$(openssl enc -pbkdf2 -a -salt -pass pass:$SALT <<< "")"
-
- # both root passwords are empty, so use the user passwords instead
- [[ $rpass == "$empty" && $rpass2 == "$empty" ]] && { rpass="$pass"; rpass2="$pass2"; }
-
- # make sure a username was entered and that the passwords match
- if [[ ${#user} -eq 0 || $user =~ \ |\' || $user =~ [^a-z0-9] || $pass == "$empty" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
- if [[ $pass == "$empty" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
- # password was left empty or doesn't match
- if [[ $pass == "$empty" ]]; then
- msgbox "$_ErrTitle" "\nUser password CANNOT be left empty.\n$_TryAgain"
- elif [[ "$rpass" != "$rpass2" ]]; then
- msgbox "$_ErrTitle" "$_RootPassErr\n$_TryAgain"
- else
- msgbox "$_ErrTitle" "$_UserPassErr\n$_TryAgain"
- fi
- else # bad username
- msgbox "$_UserErrTitle" "$_UserErrBody"
- user=""
- fi
- # recursively loop back unless the user cancels
- user || return 1
- else
- export NEWUSER="$user"
- export USER_PASS="$pass"
- export ROOT_PASS="$rpass"
- fi
- return 0
-}
-
-select_keymap() {
- tput civis
- if ! KEYMAP="$(menubox "$_PrepLayout" "$_XMapBody" 20 70 12 \
- 'us' 'English' 'cm' 'English' 'gb' 'English' 'au' 'English' 'gh' 'English' \
- 'za' 'English' 'ng' 'English' 'ca' 'French' 'cd' 'French' 'gn' 'French' \
- 'tg' 'French' 'fr' 'French' 'de' 'German' 'at' 'German' 'ch' 'German' \
- 'es' 'Spanish' 'latam' 'Spanish' 'br' 'Portuguese' 'pt' 'Portuguese' 'ma' 'Arabic' \
- 'sy' 'Arabic' 'ara' 'Arabic' 'ua' 'Ukrainian' 'cz' 'Czech' 'ru' 'Russian' \
- 'sk' 'Slovak' 'nl' 'Dutch' 'it' 'Italian' 'hu' 'Hungarian' 'cn' 'Chinese' \
- 'tw' 'Taiwanese' 'vn' 'Vietnamese' 'kr' 'Korean' 'jp' 'Japanese' 'th' 'Thai' \
- 'la' 'Lao' 'pl' 'Polish' 'se' 'Swedish' 'is' 'Icelandic' 'fi' 'Finnish' \
- 'dk' 'Danish' 'be' 'Belgian' 'in' 'Indian' 'al' 'Albanian' 'am' 'Armenian' \
- 'bd' 'Bangla' 'ba' 'Bosnian' 'bg' 'Bulgarian' 'dz' 'Berber' 'mm' 'Burmese' \
- 'hr' 'Croatian' 'gr' 'Greek' 'il' 'Hebrew' 'ir' 'Persian' 'iq' 'Iraqi' \
- 'af' 'Afghani' 'fo' 'Faroese' 'ge' 'Georgian' 'ee' 'Estonian' 'kg' 'Kyrgyz' \
- 'kz' 'Kazakh' 'lt' 'Lithuanian' 'mt' 'Maltese' 'mn' 'Mongolian' 'ro' 'Romanian' \
- 'no' 'Norwegian' 'rs' 'Serbian' 'si' 'Slovenian' 'tj' 'Tajik' 'lk' 'Sinhala' \
- 'tr' 'Turkish' 'uz' 'Uzbek' 'ie' 'Irish' 'pk' 'Urdu' 'mv' 'Dhivehi' \
- 'np' 'Nepali' 'et' 'Amharic' 'sn' 'Wolof' 'ml' 'Bambara' 'tz' 'Swahili' \
- 'ke' 'Swahili' 'bw' 'Tswana' 'ph' 'Filipino' 'my' 'Malay' 'tm' 'Turkmen' \
- 'id' 'Indonesian' 'bt' 'Dzongkha' 'lv' 'Latvian' 'md' 'Moldavian' 'mao' 'Maori' \
- 'by' 'Belarusian' 'az' 'Azerbaijani' 'mk' 'Macedonian' 'kh' 'Khmer' 'epo' 'Esperanto' \
- 'me' 'Montenegrin')"; then
- return 1
- fi
-
- # when a matching console map is not available open a selection dialog
- if [[ $CMAPS == *"$KEYMAP"* ]]; then
- CMAP="$KEYMAP"
- else
- if ! CMAP="$(menubox "$_CMapTitle" "$_CMapBody" 20 70 12 $CMAPS)"; then
- return 1
- fi
- fi
-
- if [[ $DISPLAY && $TERM != 'linux' ]]; then
- setxkbmap $KEYMAP >/dev/null 2>&1
- else
- loadkeys $CMAP >/dev/null 2>&1
- fi
- return 0
-}
-
-select_timezone() {
- # create associative array for SUBZONES[zone]
- local f="/usr/share/zoneinfo/zone.tab"
- declare -A SUBZONES
- for i in America Australia Asia Atlantic Africa Europe Indian Pacific Arctic Antarctica; do
- SUBZONES[$i]="$(awk '/'"$i"'\// {gsub(/'"$i"'\//, ""); print $3, $1}' $f)"
- done
-
- tput civis
- if ! ZONE="$(menubox "$_TimeZTitle" "$_TimeZBody" 20 70 10 \
- 'America' '-' 'Australia' '-' 'Asia' '-' 'Atlantic' '-' 'Africa' '-' \
- 'Europe' '-' 'Indian' '-' 'Pacific' '-' 'Arctic' '-' 'Antarctica' '-')"; then
- return 1
- fi
-
- if ! SUBZONE="$(menubox "$_TimeZTitle" "$_TimeSubZBody" 20 70 12 ${SUBZONES[$ZONE]})"; then
- return 1
- fi
-
- yesno "$_TimeZTitle" "$_TimeZQ $ZONE/$SUBZONE?\n" && return 0 || select_timezone
-}
-
-select_wm_or_de() {
- tput civis
- if ! INSTALL_WMS="$(dialog --cr-wrap --stdout --backtitle "$BT" \
- --title " $_WMChoice " --checklist "$_WMChoiceBody\n" 0 0 0 \
- "openbox" "A lightweight, powerful, and highly configurable stacking window manager" off \
- "bspwm" "A tiling window manager that represents windows as the leaves of a binary tree" off \
- "i3-gaps" "A fork of i3 window manager with more features including gaps" off \
- "dwm" "A customized fork of dwm, with patches and modifications" off \
- "gnome" "A desktop environment that aims to be simple and easy to use" off \
- "cinnamon" "A desktop environment combining a traditional desktop layout with modern graphical effects" off \
- "xfce4" "A lightweight and modular desktop environment based on GTK+ 2 and 3" off)"; then
- return 1
- fi
- [[ $INSTALL_WMS ]] || INSTALL_WMS='openbox'
-
- WM_NUM=$(awk '{print NF}' <<< "$INSTALL_WMS")
- WM_PACKAGES="${INSTALL_WMS/dwm/}" # remove dwm as we are compiling from source
- WM_PACKAGES="${WM_PACKAGES// / }" # remove double spaces from the string
-
- # packages needed for the selected WMs/DEs
- for wm in $INSTALL_WMS; do
- LOGIN_CHOICES="${LOGIN_CHOICES}$wm - "
- case $wm in
- cinnamon) : ;; # none
- bspwm) WM_PACKAGES+=" sxhkd" ;;
- gnome) WM_PACKAGES+=" gnome-extra" ;;
- i3-gaps) WM_PACKAGES+=" i3status perl-anyevent-i3" ;;
- xfce4) WM_PACKAGES+=" xfce4-goodies xfce4-pulseaudio-plugin" ;;
- openbox) WM_PACKAGES+=" archlabs-obkey obconf archlabs-kickshaw tint2 archlabs-skippy-xd conky jgmenu" ;;
- esac
- done
-
- if [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps) ]]; then
- WM_PACKAGES+=" libmpdclient rofi jsoncpp archlabs-screenlock termite archlabs-oblogout thunar archlabs-polybar archlabs-paranoid"
- elif [[ $INSTALL_WMS =~ (xfce4) ]]; then
- WM_PACKAGES+=" archlabs-oblogout archlabs-screenlock archlabs-paranoid"
- fi
-
- # choose how to log in
- select_login_method || return 1
-
- # choose which WM/DE to start at login
- if [[ $LOGIN_TYPE == 'xinit' ]]; then
- if [[ $WM_NUM -eq 1 ]]; then
- LOGIN_WM="$INSTALL_WMS"
- else
- if ! LOGIN_WM="$(menubox "$_WMLogin" "$_WMLoginBody" 0 0 0 $LOGIN_CHOICES)"; then
- return 1
- fi
- fi
-
- case $LOGIN_WM in
- i3-gaps) LOGIN_WM='i3' ;;
- xfce4) LOGIN_WM='startxfce4' ;;
- gnome) LOGIN_WM='gnome-session' ;;
- openbox) LOGIN_WM='openbox-session' ;;
- cinnamon) LOGIN_WM='cinnamon-session' ;;
- esac
-
- # autologin
- yesno "$_WMLogin" "$_AutoLoginBody\n" && AUTOLOGIN=true || AUTOLOGIN=false
- else
- AUTOLOGIN=false
- fi
-
- # add packages to the main package list
- PACKAGES="$WM_PACKAGES"
- return 0
-}
-
-select_login_method() {
- if ! LOGIN_TYPE="$(menubox "$_WMLogin" "$_LoginTypeBody" 0 0 0 \
- "xinit" "Console login without a display manager" \
- "lightdm" "Lightweight display manager with a gtk greeter")"; then
- return 1
- fi
- if [[ $LOGIN_TYPE == 'lightdm' ]]; then
- WM_PACKAGES+=" lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings accountsservice"
- EDIT_FILES[11]="/etc/lightdm/lightdm.conf /etc/lightdm/lightdm-gtk-greeter.conf"
- else
- EDIT_FILES[11]="/home/$NEWUSER/.xinitrc /home/$NEWUSER/.xprofile"
- fi
-}
-
-select_extra_packages() {
- local pkgs
- pkgs="$(dialog --cr-wrap --stdout --backtitle "$BT" \
- --title " $_ExtraPackages " --checklist "$_ExtraPackagesBody\n" 0 0 30 \
- "firefox" "A popular open-source graphical web browser from Mozilla" off \
- "chromium" "an open-source graphical web browser based on the Blink rendering engine" off \
- "opera" "Fast and secure, free of charge web browser from Opera Software" off \
- "epiphany" "A GNOME web browser based on the WebKit rendering engine" off \
- "qutebrowser" "A keyboard-focused vim-like web browser based on Python and PyQt5" off \
- "atom" "An open-source text editor developed by GitHub that is licensed under the MIT License" off \
- "geany" "A fast and lightweight IDE" off \
- "emacs" "An extensible, customizable, self-documenting real-time display editor" off \
- "neovim" "A fork of Vim aiming to improve user experience, plugins, and GUIs." off \
- "mousepad" "A simple text editor" off \
- "rxvt-unicode" "A unicode enabled rxvt-clone terminal emulator" off \
- "termite" "A minimal VTE-based terminal emulator" off \
- "tilix" "A tiling terminal emulator for Linux using GTK+ 3" off \
- "terminator" "Terminal emulator that supports tabs and grids" off \
- "tilda" "A Gtk based drop down terminal for Linux and Unix" off \
- "xfce4-terminal" "A terminal emulator based in the Xfce Desktop Environment" off \
- "thunar" "A modern file manager for the Xfce Desktop Environment" off \
- "pcmanfm" "A fast and lightweight file manager based in Lxde" off \
- "gnome-disk-utility" "Disk Management Utility" off \
- "gnome-system-monitor" "View current processes and monitor system state" off \
- "steam" "A popular game distribution platform by Valve" off \
- "vlc" "A free and open source cross-platform multimedia player" off \
- "mpd" "A flexible, powerful, server-side application for playing music" off \
- "ncmpcpp" "An mpd client and almost exact clone of ncmpc with some new features" off \
- "cmus" "A small, fast and powerful console music player for Unix-like operating systems" off \
- "audacious" "A free and advanced audio player based on GTK+" off \
- "nicotine+" "A graphical client for Soulseek" off \
- "lollypop" "A new music playing application" off \
- "rhythmbox" "Music playback and management application" off \
- "deadbeef" "A GTK+ audio player for GNU/Linux" off \
- "clementine" "A modern music player and library organizer" off \
- "thunderbird" "Standalone mail and news reader from mozilla" off \
- "geary" "A lightweight email client for the GNOME desktop" off \
- "evolution" "Manage your email, contacts and schedule" off \
- "mutt" "Small but very powerful text-based mail client" off \
- "deluge" "A BitTorrent client written in python" off \
- "transmission-gtk" "Free BitTorrent client GTK+ GUI" off \
- "qbittorrent" "An advanced BitTorrent client" off \
- "hexchat" "A popular and easy to use graphical IRC client" off \
- "pidgin" "Multi-protocol instant messaging client" off \
- "weechat" "Fast, light and extensible IRC client" off \
- "irssi" "Modular text mode IRC client" off \
- "libreoffice-fresh" "Full featured office suite" off \
- "abiword" "Fully-featured word processor" off \
- "calligra" "A set of applications for productivity" off \
- "evince" "A document viewer" off \
- "zathura" "Minimalistic document viewer" off \
- "qpdfview" "A tabbed PDF viewer" off \
- "mupdf" "Lightweight PDF and XPS viewer" off \
- "gpicview" "Lightweight image viewer" off \
- "gimp" "GNU Image Manipulation Program" off \
- "inkscape" "Professional vector graphics editor" off \
- "krita" "Edit and paint images" off \
- "simplescreenrecorder" "A feature-rich screen recorder" off \
- "obs-studio" "Free opensource streaming/recording software" off \
- "openshot" "An open-source, non-linear video editor for Linux based on MLT framework" off \
- "kdenlive" "A non-linear video editor for Linux using the MLT video framework" off \
- "audacity" "A program that lets you manipulate digital audio waveforms" off \
- "guvcview" "Capture video from camera devices" off \
- "gpick" "Advanced color picker using GTK+ toolkit" off \
- "gcolor2" "A simple GTK+2 color selector" off \
- "plank" "An elegant, simple, and clean dock" off \
- "docky" "Full fledged dock that makes opening applications and managing windows faster and easier" off \
- "cairo-dock" "Light eye-candy fully themable animated dock" off \
- "qt5ct" "GUI for managing Qt based application themes, icons, and fonts" off \
- "ttf-hack" "A hand groomed and optically balanced typeface based on Bitstream Vera Mono" off \
- "ttf-anonymous-pro" "A family of four fixed-width fonts designed especially with coding in mind" off \
- "ttf-font-awesome" "Iconic font designed for Bootstrap" off \
- "ttf-fira-code" "Monospaced font with programming ligatures" off \
- "noto-fonts" "Google Noto fonts" off \
- "noto-fonts-cjk" "Google Noto CJK fonts (Chinese, Japanese, Korean)" off)"
-
- [[ $pkgs =~ vlc ]] && pkgs+=" qt4"
- [[ $pkgs =~ mpd ]] && pkgs+=" mpc"
- [[ $pkgs =~ mupdf ]] && pkgs+=" mupdf-tools"
- [[ $pkgs =~ qt5ct ]] && pkgs+=" qt5-styleplugins"
- [[ $pkgs =~ steam ]] && pkgs+=" steam-native-runtime"
- [[ $pkgs =~ zathura ]] && pkgs+=" zathura-pdf-poppler"
- [[ $pkgs =~ noto-fonts ]] && pkgs+=" noto-fonts-emoji"
- [[ $pkgs =~ cairo-dock ]] && pkgs+=" cairo-dock-plug-ins"
- [[ $pkgs =~ kdenlive ]] && pkgs+=" kdebase-runtime dvdauthor frei0r-plugins breeze breeze-gtk"
- { [[ $INSTALL_WMS =~ dwm ]] && ! [[ $pkgs =~ ttf-hack ]]; } && pkgs+=" ttf-hack"
- { [[ $pkgs =~ (qutebrowser|qbittorrent|kdenlive|vlc) ]] && ! [[ $pkgs =~ qt5ct ]]; } && pkgs+=" qt5ct qt5-styleplugins"
-
- PACKAGES+=" $pkgs" # add chosen packages to the main package list
- PACKAGES="${PACKAGES/^ /}" # remove leading spaces from the package string
- return 0
-}
-
-select_mirrorlist_command() {
- local ip c
- local key="5f29642060ab983b31fdf4c2935d8c56"
-
- if hash reflector >/dev/null 2>&1; then
- MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate --verbose"
- yesno "$_MirrorTitle" "$_MirrorSetup" "Automatic" "Custom" && return 0
-
- ip="$(json 'ip' "check&?access_key=${key}&fields=ip")"
- c="$(json 'country_name' "${ip}?access_key=${key}&fields=country_name")"
- MIRROR_CMD="reflector --country $c --score 80 --latest 40 --fastest 10 --sort rate --verbose"
-
- tput cnorm
- MIRROR_CMD="$(dialog --cr-wrap --no-cancel --stdout --backtitle "$BT" \
- --title " $_MirrorTitle " --inputbox "$_MirrorCmd\n
- --score n Limit the list to the n servers with the highest score.
- --latest n Limit the list to the n most recently synchronized servers.
- --fastest n Return the n fastest mirrors that meet the other criteria.
- --sort {age,rate,country,score,delay}
-
- 'age': Last server synchronization;
- 'rate': Download rate;
- 'country': Server location;
- 'score': MirrorStatus score;
- 'delay': MirrorStatus delay.\n" 0 0 "$MIRROR_CMD")"
- else
- ip="$(json 'ip' "check&?access_key=${key}&fields=ip")"
- c="$(json 'country_code' "${ip}?access_key=${key}&fields=country_code")"
- local w="https://www.archlinux.org/mirrorlist"
- if [[ $c ]]; then
- if [[ $c =~ (CA|US) ]]; then
- MIRROR_CMD="curl -s '$w/?country=US&country=CA&protocol=https&use_mirror_status=on'"
- else
- MIRROR_CMD="curl -s '$w/?country=${c}&protocol=https&use_mirror_status=on'"
- fi
- else
- MIRROR_CMD="curl -s '$w/?country=US&country=CA&country=NZ&country=GB&country=AU&protocol=https&use_mirror_status=on'"
- fi
- fi
- return 0
-}
-
-display_system_settings() {
- local cmd mnt pkgs
- cmd="${BCMDS[$BOOTLDR]}"
- mnt="${BMNTS[$SYS-$BOOTLDR]}"
- msgbox "$_PrepTitle" "\n\n---------- PARTITION CONFIGURATION ------------
-
- Root: ${ROOT_PART:-None}
- Boot: ${BOOT_PART:-${BOOT_DEVICE:-None}}
-
- Swap: ${SWAP_PART:-None}
- Size: ${SWAP_SIZE:-None}
-
- Extra: ${EXTRA_MNTS:-${EXTRA_MNT:-None}}
- Hooks: ${MKINIT_HOOKS:-None}
-
- LVM: ${LVM:-None}
- LUKS: ${LUKS:-None}
-
-
----------- BOOTLOADER CONFIGURATION -----------
-
- Loader: ${BOOTLDR:-None}
- Mount: ${mnt:-None}
- Command: ${cmd:-None}
-
-
------------- SYSTEM CONFIGURATION -------------
-
- Locale: ${LOCALE:-None}
- Keymap: ${KEYMAP:-None}
- Hostname: ${HOSTNAME:-None}
- Timezone: ${ZONE:-None}/${SUBZONE:-None}
-
-
------------- LOGIN CONFIGURATION --------------
-
- User: ${NEWUSER:-None}
- Shell: ${MYSHELL:-None}
- Session: ${LOGIN_WM:-None}
- Autologin: ${AUTOLOGIN:-None}
- Management: ${LOGIN_TYPE:-None}
-
-
------------- PACKAGES AND MIRRORS -------------
-
- Kernel: ${KERNEL:-None}
- Sessions: ${INSTALL_WMS:-None}
- Mirrors: ${MIRROR_CMD:-None}
- Packages: $(printq "${PACKAGES:-None}")\n"
-}
-
-configure_system_settings() {
- tput cnorm
- if ! HOSTNAME="$(getinput "$_ConfHost" "$_HostNameBody" "${DIST,,}")"; then
- return 1
- fi
-
- tput civis
- if ! LOCALE="$(menubox "$_ConfLocale" "$_LocaleBody" 25 70 20 $LOCALES)"; then
- return 1
- fi
-
- select_timezone || return 1
- user_creation || return 1
-
- tput civis
- if ! MYSHELL="$(menubox "$_ShellTitle" "$_ShellBody" 0 0 0 '/bin/zsh' '-' '/bin/bash' '-')"; then
- return 1
- fi
-
- tput civis
- if [[ $HAS_NETWORK == true ]]; then
- if ! KERNEL="$(menubox "$_KernelTitle" "$_KernelBody" 0 0 0 'linux' '-' 'linux-lts' '-')"; then
- return 1
- fi
-
- select_wm_or_de || return 1
- select_extra_packages || return 1
- select_mirrorlist_command || return 1
- else
- # defaults for when there is no network connection
- KERNEL='linux'
- AUTOLOGIN=true
- LOGIN_TYPE='xinit'
- INSTALL_WMS='openbox'
- LOGIN_WM='openbox-session'
- MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate --verbose"
- EDIT_FILES[11]="/home/$NEWUSER/.xinitrc /home/$NEWUSER/.xprofile"
- fi
-
- export CONFIG_DONE=true
- return 0
-}
-
-edit_system_configs() {
- if [[ $CURRENT_MENU != "edit" ]]; then
- SELECTED=1; CURRENT_MENU="edit"
- elif (( SELECTED < 11 )); then
- (( SELECTED++ ))
- fi
-
- tput civis
- local exitstr
- [[ $DEBUG == true ]] && exitstr="View Log & Reboot" || exitstr="Reboot"
-
- SELECTED=$(dialog --cr-wrap --stdout --backtitle "$BT" \
- --title " $_EditTitle " --default-item $SELECTED --menu "$_EditBody" 0 0 0 \
- "1" "$exitstr" "2" "Keyboard" "3" "Locale" "4" "Hostname" \
- "5" "Sudoers" "6" "Mkinitcpio.conf" "7" "Fstab" "8" "Crypttab" \
- "9" "${BOOTLDR^}" "10" "Pacman.conf" "11" "${LOGIN_TYPE^}")
-
- if [[ ! $SELECTED || $SELECTED -eq 1 ]]; then
- [[ $DEBUG == true ]] && more $DEBUG
- die 127
- else
- local existing_files=""
- for f in $(printf "%s" "${EDIT_FILES[$SELECTED]}"); do
- [[ -e ${MNT}$f ]] && existing_files+=" ${MNT}$f"
- done
- if [[ ! $existing_files ]]; then
- msgbox "$_ErrTitle" "$_NoFileErr"
- else
- if hash vim >/dev/null 2>&1; then
- vim -O $existing_files
- else
- for f in $existing_files; do
- if hash nano >/dev/null 2>&1; then
- nano $f
- else
- vi $f
- fi
- done
- fi
- fi
- fi
- edit_system_configs
-}
-
main() {
if [[ $CURRENT_MENU != "main" ]]; then
SELECTED=1
@@ -596,12 +33,13 @@ main() {
# and that the needed config variables and user variables have been set up
if [[ $SELECTED ]]; then
if [[ $SELECTED -eq 8 || $SELECTED -eq 6 ]]; then
- { [[ $SELECTED -eq 8 ]] && icheck 1 || icheck; } || return 1
+ { [[ $SELECTED -eq 8 ]] && preinstall_check 1 || preinstall_check; } || return 1
elif [[ ($SELECTED -eq 2 || $SELECTED -eq 5) && $WARN != true ]]; then
msgbox "$_PrepTitle" "$_WarnMount" && WARN=true
fi
fi
+ # setting $SELECTED to $SELECTED - 1 when a step fails retains the highlighted menu item
case $SELECTED in
1) device_tree ;;
2) partition || SELECTED=1 ;;
@@ -627,12 +65,14 @@ for arg in "$@"; do case $arg in
--debug|-d) debug ;;
esac done
-# initial choices/prep
-devices
+# initial prep
select_language
select_keymap
-checks
-sysid
+
+# call checks before identify so we can try mounting efivarfs
+system_checks
+system_identify
+system_devices
# welcome message
msgbox "$_WelTitle $DIST Installer" "$_WelBody"
diff --git a/src/lib/boot.sh b/src/lib/boot.sh
index 2d7bc9a..7eece0a 100644
--- a/src/lib/boot.sh
+++ b/src/lib/boot.sh
@@ -6,8 +6,6 @@
# this file is not meant to be run directly
# sourcing this file in a non bash shell is not advised
-# set -n
-
declare -gA BCMDS=(
[syslinux]="syslinux-install_update -iam"
[grub]="grub-install --recheck --force"
diff --git a/src/lib/dialogs.sh b/src/lib/dialogs.sh
new file mode 100644
index 0000000..30180a4
--- /dev/null
+++ b/src/lib/dialogs.sh
@@ -0,0 +1,601 @@
+#!/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,2034,2153
+
+# mutable globals {
+declare -g WARN=false
+declare -g AUTOLOGIN=false
+declare -g CONFIG_DONE=false
+declare -g SEPERATE_BOOT=false
+declare -g HAS_NETWORK=false
+
+declare -g BT="$DIST Installer - (x86_64) - Version $VER"
+declare -g ROOT_PART=""
+declare -g BOOT_DEVICE=""
+declare -g BOOT_PART=""
+declare -g BOOTLDR=""
+declare -g EXTRA_MNT=""
+declare -g EXTRA_MNTS=""
+declare -g SWAP_PART=""
+declare -g SWAP_SIZE=""
+declare -g NEWUSER=""
+declare -g USER_PASS=""
+declare -g ROOT_PASS=""
+declare -g LOGIN_WM=""
+declare -g LOGIN_TYPE=""
+declare -g INSTALL_WMS=""
+declare -g KERNEL=""
+declare -g WM_PACKAGES=""
+declare -g PACKAGES=""
+declare -g MYSHELL=""
+declare -g MKINIT_HOOKS="shutdown"
+
+# package extras
+# if you add a package to $PACKAGES in any dialog and it uses or requires some
+# additional packages, you can add them here to keep it simple for the end user
+declare -gA PKG_EXT=(
+[vlc]="qt4"
+[mpd]="mpc"
+[mupdf]="mupdf-tools"
+[qt5ct]="qt5-styleplugins"
+[steam]="steam-native-runtime"
+[zathura]="zathura-pdf-poppler"
+[cairo-dock]="cairo-dock-plug-ins"
+[noto-fonts]="noto-fonts-emoji"
+[kdenlive]="kdebase-runtime dvdauthor frei0r-plugins breeze breeze-gtk"
+[vlc]="qt5ct qt5-styleplugins"
+[kdenlive]="qt5ct qt5-styleplugins" # duplicates are stripped with `uniq` later
+[qbittorrent]="qt5ct qt5-styleplugins"
+[qutebrowser]="qt5ct qt5-styleplugins"
+)
+
+# }
+
+
+# basic dialog helper functions
+
+msgbox() {
+ tput civis
+ dialog --cr-wrap --backtitle "$BT" --title " $1 " --msgbox "$2\n" 0 0
+}
+
+menubox() {
+ local title="$1"
+ local body="$2"
+ local h=$3
+ local w=$4
+ local n=$5
+ shift 5
+ local response
+ if ! response="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $title " --menu "$body" $h $w $n "$@")"; then
+ return 1
+ fi
+ printf "%s" "$response"
+}
+
+checkbox() {
+ local title="$1"
+ local body="$2"
+ local h=$3
+ local w=$4
+ local n=$5
+ shift 5
+ local response
+ if ! response="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $title " --checklist "$body" $h $w $n "$@")"; then
+ return 1
+ fi
+ printf "%s" "$response"
+}
+
+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}
+}
+
+yesno() {
+ # usage: yesno
[ []]
+ # 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
+}
+
+# larger specific dialog menus
+
+select_language() {
+ tput civis
+ local lang
+ local title="\nLanguage - sprache - taal - språk - lingua - idioma - nyelv - língua\n"
+ lang=$(menubox "Select Language" "$title" 0 0 0 \
+ "1" "English (en_**)" "2" "Español (es_ES)" \
+ "3" "Português [Brasil] (pt_BR)" "4" "Português (pt_PT)" \
+ "5" "Français (fr_FR)" "6" "Russkiy (ru_RU)" \
+ "7" "Italiano (it_IT)" "8" "Nederlands (nl_NL)" \
+ "9" "Magyar (hu_HU)" "10" "Chinese (zh_CN)")
+
+ local srcdir="/usr/share/archlabs/installer/lang"
+ src $srcdir/english.trans
+ FONT="ter-i16n"
+
+ case $lang in
+ 1) LOC="en_US.UTF-8" ;;
+ 2) src $srcdir/spanish.trans && LOC="es_ES.UTF-8" ;;
+ 3) src $srcdir/p_brasil.trans && LOC="pt_BR.UTF-8" ;;
+ 4) src $srcdir/portuguese.trans && LOC="pt_PT.UTF-8" ;;
+ 5) src $srcdir/french.trans && LOC="fr_FR.UTF-8" ;;
+ 6) src $srcdir/russian.trans && LOC="ru_RU.UTF-8" FONT="LatKaCyrHeb-16" ;;
+ 7) src $srcdir/italian.trans && LOC="it_IT.UTF-8" ;;
+ 8) src $srcdir/dutch.trans && LOC="nl_NL.UTF-8" ;;
+ 9) src $srcdir/hungarian.trans && LOC="hu_HU.UTF-8" FONT="lat2-16" ;;
+ 10) src $srcdir/chinese.trans && LOC="zh_CN.UTF-8" ;;
+ *) die
+ esac
+
+ sed -i "s/#en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen
+ if [[ $LOC != "en_US.UTF-8" ]]; then
+ sed -i "s/#${LOC}/${LOC}/" /etc/locale.gen
+ locale-gen >/dev/null 2>&1
+ fi
+ [[ $TERM == 'linux' ]] && setfont $FONT >/dev/null 2>&1
+ export LANG="$LOC"
+ return 0
+}
+
+user_creation() {
+ tput cnorm
+ local values
+ if ! values="$(dialog --stdout --no-cancel --separator '~' --ok-label "Submit" --backtitle "$BT" \
+ --title " $_UserTitle " --insecure --mixedform "$_UserBody" 27 75 10 \
+ "$_Username" 1 1 "" 1 $((${#_Username} + 2)) 71 0 0 \
+ "$_Password" 2 1 "" 2 $((${#_Password} + 2)) 71 0 1 \
+ "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) 71 0 1 \
+ "$_RootBody" 6 1 "" 6 $((${#_RootBody} + 1)) 71 0 2 \
+ "$_Password" 8 1 "" 8 $((${#_Password} + 2)) 71 0 1 \
+ "$_Password2" 9 1 "" 9 $((${#_Password2} + 2)) 71 0 1 |
+ openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"; then
+ return 1
+ fi
+
+ # username doesn't need to be re-encrypted
+ local user
+ user="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
+ awk -F'~' '{print $1}')"
+
+ # all of this is a bit hacky, but we don't ever want the passwords to be stored in plain text
+ # so it decrypts the string '$values', gets the field we want, and re-encrypts it
+ local pass pass2
+ pass="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
+ awk -F'~' '{print $2}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
+ pass2="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
+ awk -F'~' '{print $3}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
+
+ local rpass rpass2
+ rpass="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
+ awk -F'~' '{print $5}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
+ rpass2="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
+ awk -F'~' '{print $6}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
+
+ # due to encrypting the string, when empty, once encrypted it wont be empty
+ local empty
+ empty="$(openssl enc -pbkdf2 -a -salt -pass pass:$SALT <<< "")"
+
+ # both root passwords are empty, so use the user passwords instead
+ [[ $rpass == "$empty" && $rpass2 == "$empty" ]] && { rpass="$pass"; rpass2="$pass2"; }
+
+ # make sure a username was entered and that the passwords match
+ if [[ ${#user} -eq 0 || $user =~ \ |\' || $user =~ [^a-z0-9] || $pass == "$empty" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
+ if [[ $pass == "$empty" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
+ # password was left empty or doesn't match
+ if [[ $pass == "$empty" ]]; then
+ msgbox "$_ErrTitle" "\nUser password CANNOT be left empty.\n$_TryAgain"
+ elif [[ "$rpass" != "$rpass2" ]]; then
+ msgbox "$_ErrTitle" "$_RootPassErr\n$_TryAgain"
+ else
+ msgbox "$_ErrTitle" "$_UserPassErr\n$_TryAgain"
+ fi
+ else # bad username
+ msgbox "$_UserErrTitle" "$_UserErrBody"
+ user=""
+ fi
+ # recursively loop back unless the user cancels
+ user || return 1
+ else
+ export NEWUSER="$user"
+ export USER_PASS="$pass"
+ export ROOT_PASS="$rpass"
+ fi
+ return 0
+}
+
+select_keymap() {
+ tput civis
+ if ! KEYMAP="$(menubox "$_PrepLayout" "$_XMapBody" 20 70 12 \
+ 'us' 'English' 'cm' 'English' 'gb' 'English' 'au' 'English' 'gh' 'English' \
+ 'za' 'English' 'ng' 'English' 'ca' 'French' 'cd' 'French' 'gn' 'French' \
+ 'tg' 'French' 'fr' 'French' 'de' 'German' 'at' 'German' 'ch' 'German' \
+ 'es' 'Spanish' 'latam' 'Spanish' 'br' 'Portuguese' 'pt' 'Portuguese' 'ma' 'Arabic' \
+ 'sy' 'Arabic' 'ara' 'Arabic' 'ua' 'Ukrainian' 'cz' 'Czech' 'ru' 'Russian' \
+ 'sk' 'Slovak' 'nl' 'Dutch' 'it' 'Italian' 'hu' 'Hungarian' 'cn' 'Chinese' \
+ 'tw' 'Taiwanese' 'vn' 'Vietnamese' 'kr' 'Korean' 'jp' 'Japanese' 'th' 'Thai' \
+ 'la' 'Lao' 'pl' 'Polish' 'se' 'Swedish' 'is' 'Icelandic' 'fi' 'Finnish' \
+ 'dk' 'Danish' 'be' 'Belgian' 'in' 'Indian' 'al' 'Albanian' 'am' 'Armenian' \
+ 'bd' 'Bangla' 'ba' 'Bosnian' 'bg' 'Bulgarian' 'dz' 'Berber' 'mm' 'Burmese' \
+ 'hr' 'Croatian' 'gr' 'Greek' 'il' 'Hebrew' 'ir' 'Persian' 'iq' 'Iraqi' \
+ 'af' 'Afghani' 'fo' 'Faroese' 'ge' 'Georgian' 'ee' 'Estonian' 'kg' 'Kyrgyz' \
+ 'kz' 'Kazakh' 'lt' 'Lithuanian' 'mt' 'Maltese' 'mn' 'Mongolian' 'ro' 'Romanian' \
+ 'no' 'Norwegian' 'rs' 'Serbian' 'si' 'Slovenian' 'tj' 'Tajik' 'lk' 'Sinhala' \
+ 'tr' 'Turkish' 'uz' 'Uzbek' 'ie' 'Irish' 'pk' 'Urdu' 'mv' 'Dhivehi' \
+ 'np' 'Nepali' 'et' 'Amharic' 'sn' 'Wolof' 'ml' 'Bambara' 'tz' 'Swahili' \
+ 'ke' 'Swahili' 'bw' 'Tswana' 'ph' 'Filipino' 'my' 'Malay' 'tm' 'Turkmen' \
+ 'id' 'Indonesian' 'bt' 'Dzongkha' 'lv' 'Latvian' 'md' 'Moldavian' 'mao' 'Maori' \
+ 'by' 'Belarusian' 'az' 'Azerbaijani' 'mk' 'Macedonian' 'kh' 'Khmer' 'epo' 'Esperanto' \
+ 'me' 'Montenegrin')"; then
+ return 1
+ fi
+
+ # when a matching console map is not available open a selection dialog
+ if [[ $CMAPS == *"$KEYMAP"* ]]; then
+ CMAP="$KEYMAP"
+ else
+ if ! CMAP="$(menubox "$_CMapTitle" "$_CMapBody" 20 70 12 $CMAPS)"; then
+ return 1
+ fi
+ fi
+
+ if [[ $DISPLAY && $TERM != 'linux' ]]; then
+ setxkbmap $KEYMAP >/dev/null 2>&1
+ else
+ loadkeys $CMAP >/dev/null 2>&1
+ fi
+ return 0
+}
+
+select_timezone() {
+ # create associative array for SUBZONES[zone]
+ local f="/usr/share/zoneinfo/zone.tab"
+ declare -A SUBZONES
+ for i in America Australia Asia Atlantic Africa Europe Indian Pacific Arctic Antarctica; do
+ SUBZONES[$i]="$(awk '/'"$i"'\// {gsub(/'"$i"'\//, ""); print $3, $1}' $f)"
+ done
+
+ tput civis
+ if ! ZONE="$(menubox "$_TimeZTitle" "$_TimeZBody" 20 70 10 \
+ 'America' '-' 'Australia' '-' 'Asia' '-' 'Atlantic' '-' 'Africa' '-' \
+ 'Europe' '-' 'Indian' '-' 'Pacific' '-' 'Arctic' '-' 'Antarctica' '-')"; then
+ return 1
+ fi
+
+ if ! SUBZONE="$(menubox "$_TimeZTitle" "$_TimeSubZBody" 20 70 12 ${SUBZONES[$ZONE]})"; then
+ return 1
+ fi
+
+ yesno "$_TimeZTitle" "$_TimeZQ $ZONE/$SUBZONE?\n" && return 0 || select_timezone
+}
+
+select_wm_or_de() {
+ declare -g PACKAGES=""
+
+ tput civis
+ if ! INSTALL_WMS="$(dialog --cr-wrap --stdout --backtitle "$BT" \
+ --title " $_WMChoice " --checklist "$_WMChoiceBody\n" 0 0 0 \
+ "openbox" "A lightweight, powerful, and highly configurable stacking window manager" off \
+ "bspwm" "A tiling window manager that represents windows as the leaves of a binary tree" off \
+ "i3-gaps" "A fork of i3 window manager with more features including gaps" off \
+ "dwm" "A customized fork of dwm, with patches and modifications" off \
+ "gnome" "A desktop environment that aims to be simple and easy to use" off \
+ "cinnamon" "A desktop environment combining a traditional desktop layout with modern graphical effects" off \
+ "xfce4" "A lightweight and modular desktop environment based on GTK+ 2 and 3" off)"; then
+ return 1
+ fi
+ [[ $INSTALL_WMS ]] || INSTALL_WMS='openbox'
+
+ WM_NUM=$(awk '{print NF}' <<< "$INSTALL_WMS")
+ WM_PACKAGES="${INSTALL_WMS/dwm/}" # remove dwm as we are compiling from source
+ WM_PACKAGES="${WM_PACKAGES// / }" # remove double spaces from the string
+
+ # packages needed for the selected WMs/DEs
+ for wm in $INSTALL_WMS; do
+ LOGIN_CHOICES="${LOGIN_CHOICES}$wm - "
+ case $wm in
+ dwm) WM_PACKAGES+=" ttf-hack" ;;
+ bspwm) WM_PACKAGES+=" sxhkd" ;;
+ gnome) WM_PACKAGES+=" gnome-extra" ;;
+ i3-gaps) WM_PACKAGES+=" i3status perl-anyevent-i3" ;;
+ xfce4) WM_PACKAGES+=" xfce4-goodies xfce4-pulseaudio-plugin" ;;
+ openbox) WM_PACKAGES+=" archlabs-obkey obconf archlabs-kickshaw tint2 archlabs-skippy-xd conky jgmenu" ;;
+ esac
+ done
+
+ if [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps) ]]; then
+ WM_PACKAGES+=" libmpdclient jsoncpp archlabs-screenlock termite archlabs-oblogout archlabs-polybar archlabs-paranoid rofi thunar"
+ elif [[ $INSTALL_WMS =~ xfce4 ]]; then
+ WM_PACKAGES+=" archlabs-oblogout archlabs-screenlock archlabs-paranoid"
+ fi
+
+ # choose how to log in
+ select_login_method || return 1
+
+ # choose which WM/DE to start at login
+ if [[ $LOGIN_TYPE == 'xinit' ]]; then
+ if [[ $WM_NUM -eq 1 ]]; then
+ LOGIN_WM="$INSTALL_WMS"
+ else
+ if ! LOGIN_WM="$(menubox "$_WMLogin" "$_WMLoginBody" 0 0 0 $LOGIN_CHOICES)"; then
+ return 1
+ fi
+ fi
+
+ case $LOGIN_WM in
+ i3-gaps) LOGIN_WM='i3' ;;
+ xfce4) LOGIN_WM='startxfce4' ;;
+ gnome) LOGIN_WM='gnome-session' ;;
+ openbox) LOGIN_WM='openbox-session' ;;
+ cinnamon) LOGIN_WM='cinnamon-session' ;;
+ esac
+
+ # autologin
+ yesno "$_WMLogin" "$_AutoLoginBody\n" && AUTOLOGIN=true || AUTOLOGIN=false
+ else
+ AUTOLOGIN=false
+ fi
+
+ # add packages to the main package list
+ PACKAGES="$WM_PACKAGES"
+ return 0
+}
+
+select_login_method() {
+ if ! LOGIN_TYPE="$(menubox "$_WMLogin" "$_LoginTypeBody" 0 0 0 \
+ "xinit" "Console login without a display manager" \
+ "lightdm" "Lightweight display manager with a gtk greeter")"; then
+ return 1
+ fi
+ if [[ $LOGIN_TYPE == 'lightdm' ]]; then
+ WM_PACKAGES+=" lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings accountsservice"
+ EDIT_FILES[11]="/etc/lightdm/lightdm.conf /etc/lightdm/lightdm-gtk-greeter.conf"
+ else
+ EDIT_FILES[11]="/home/$NEWUSER/.xinitrc /home/$NEWUSER/.xprofile"
+ fi
+}
+
+select_packages() {
+ if [[ $CURRENT_MENU != "packages" ]]; then
+ SELECTED=1
+ CURRENT_MENU="packages"
+ elif (( SELECTED < 9 )); then
+ ((SELECTED++)) # increment the highlighted menu item
+ fi
+
+ tput civis
+ SELECTED=$(dialog --cr-wrap --stdout --backtitle "$BT" \
+ --title " $_Packages " --default-item $SELECTED --menu "$_PackageMenu" 0 0 0 \
+ "1" "Web Browsers" "2" "Text Editors" "3" "Terminal Emulators" \
+ "4" "Music and Video Players" "5" "Mail and Chat" "6" "Office and Editing" \
+ "7" "Management and Fonts" "8" "Miscellaneous" "9" "$_Done")
+
+ if [[ $SELECTED -lt 9 ]]; then
+ case $SELECTED in
+ 1) PACKAGES+=" $(select_browsers)" ;;
+ 2) PACKAGES+=" $(select_editors)" ;;
+ 3) PACKAGES+=" $(select_terminals)" ;;
+ 4) PACKAGES+=" $(select_music_and_video)" ;;
+ 5) PACKAGES+=" $(select_mail_and_chat)" ;;
+ 6) PACKAGES+=" $(select_office_and_editing)" ;;
+ 7) PACKAGES+=" $(select_managment)" ;;
+ 8) PACKAGES+=" $(select_extra)" ;;
+ esac
+ select_packages
+ else
+ # add any extra for each package
+ for pkg in $PACKAGES; do
+ [[ ${PKG_EXT[$pkg]} ]] && PACKAGES+=" ${PKG_EXT[$pkg]}"
+ done
+
+ # remove duplicates and leading spaces
+ PACKAGES="$(uniq <<< "${PACKAGES/^ /}")"
+ return 0
+ fi
+}
+
+select_mirrorcmd() {
+ local ip c
+ local key="5f29642060ab983b31fdf4c2935d8c56"
+
+ if hash reflector >/dev/null 2>&1; then
+ MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate --verbose"
+ yesno "$_MirrorTitle" "$_MirrorSetup" "Automatic" "Custom" && return 0
+
+ ip="$(json 'ip' "check&?access_key=${key}&fields=ip")"
+ c="$(json 'country_name' "${ip}?access_key=${key}&fields=country_name")"
+ MIRROR_CMD="reflector --country $c --score 80 --latest 40 --fastest 10 --sort rate --verbose"
+
+ tput cnorm
+ MIRROR_CMD="$(dialog --cr-wrap --no-cancel --stdout --backtitle "$BT" \
+ --title " $_MirrorTitle " --inputbox "$_MirrorCmd\n
+ --score n Limit the list to the n servers with the highest score.
+ --latest n Limit the list to the n most recently synchronized servers.
+ --fastest n Return the n fastest mirrors that meet the other criteria.
+ --sort {age,rate,country,score,delay}
+
+ 'age': Last server synchronization;
+ 'rate': Download rate;
+ 'country': Server location;
+ 'score': MirrorStatus score;
+ 'delay': MirrorStatus delay.\n" 0 0 "$MIRROR_CMD")"
+ else
+ ip="$(json 'ip' "check&?access_key=${key}&fields=ip")"
+ c="$(json 'country_code' "${ip}?access_key=${key}&fields=country_code")"
+ local w="https://www.archlinux.org/mirrorlist"
+ if [[ $c ]]; then
+ if [[ $c =~ (CA|US) ]]; then
+ MIRROR_CMD="curl -s '$w/?country=US&country=CA&protocol=https&use_mirror_status=on'"
+ else
+ MIRROR_CMD="curl -s '$w/?country=${c}&protocol=https&use_mirror_status=on'"
+ fi
+ else
+ MIRROR_CMD="curl -s '$w/?country=US&country=CA&country=NZ&country=GB&country=AU&protocol=https&use_mirror_status=on'"
+ fi
+ fi
+ return 0
+}
+
+display_system_settings() {
+ local cmd mnt pkgs
+ cmd="${BCMDS[$BOOTLDR]}"
+ mnt="${BMNTS[$SYS-$BOOTLDR]}"
+ msgbox "$_PrepTitle" "
+
+---------- PARTITION CONFIGURATION ------------
+
+ Root: ${ROOT_PART:-None}
+ Boot: ${BOOT_PART:-${BOOT_DEVICE:-None}}
+
+ Swap: ${SWAP_PART:-None}
+ Size: ${SWAP_SIZE:-None}
+
+ Extra: ${EXTRA_MNTS:-${EXTRA_MNT:-None}}
+ Hooks: ${MKINIT_HOOKS:-None}
+
+ LVM: ${LVM:-None}
+ LUKS: ${LUKS:-None}
+
+
+---------- BOOTLOADER CONFIGURATION -----------
+
+ Loader: ${BOOTLDR:-None}
+ Mount: ${mnt:-None}
+ Command: ${cmd:-None}
+
+
+------------ SYSTEM CONFIGURATION -------------
+
+ Locale: ${LOCALE:-None}
+ Keymap: ${KEYMAP:-None}
+ Hostname: ${HOSTNAME:-None}
+ Timezone: ${ZONE:-None}/${SUBZONE:-None}
+
+
+------------ LOGIN CONFIGURATION --------------
+
+ User: ${NEWUSER:-None}
+ Shell: ${MYSHELL:-None}
+ Session: ${LOGIN_WM:-None}
+ Autologin: ${AUTOLOGIN:-None}
+ Management: ${LOGIN_TYPE:-None}
+
+
+------------ PACKAGES AND MIRRORS -------------
+
+ Kernel: ${KERNEL:-None}
+ Sessions: ${INSTALL_WMS:-None}
+ Mirrors: ${MIRROR_CMD:-None}
+ Packages: $(print4 "${PACKAGES:-None}")
+"
+}
+
+configure_system_settings() {
+ tput cnorm
+ if ! HOSTNAME="$(getinput "$_ConfHost" "$_HostNameBody" "${DIST,,}")"; then
+ return 1
+ fi
+
+ tput civis
+ if ! LOCALE="$(menubox "$_ConfLocale" "$_LocaleBody" 25 70 20 $LOCALES)"; then
+ return 1
+ fi
+
+ select_timezone || return 1
+ user_creation || return 1
+
+ tput civis
+ if ! MYSHELL="$(menubox "$_ShellTitle" "$_ShellBody" 0 0 0 '/bin/zsh' '-' '/bin/bash' '-')"; then
+ return 1
+ fi
+
+ tput civis
+ if [[ $HAS_NETWORK == true ]]; then
+ if ! KERNEL="$(menubox "$_KernelTitle" "$_KernelBody" 0 0 0 'linux' '-' 'linux-lts' '-')"; then
+ return 1
+ fi
+ select_wm_or_de || return 1
+ select_packages || return 1
+ select_mirrorcmd || return 1
+ else
+ # defaults for when there is no network connection
+ KERNEL='linux'
+ AUTOLOGIN=true
+ LOGIN_TYPE='xinit'
+ INSTALL_WMS='openbox'
+ LOGIN_WM='openbox-session'
+ MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate --verbose"
+ EDIT_FILES[11]="/home/$NEWUSER/.xinitrc /home/$NEWUSER/.xprofile"
+ fi
+
+ export CONFIG_DONE=true
+ return 0
+}
+
+edit_system_configs() {
+ if [[ $CURRENT_MENU != "edit" ]]; then
+ SELECTED=1; CURRENT_MENU="edit"
+ elif (( SELECTED < 11 )); then
+ (( SELECTED++ ))
+ fi
+
+ tput civis
+ local exitstr
+ [[ $DEBUG == true ]] && exitstr="View debug log before the exit & reboot" || exitstr="Exit & reboot"
+
+ SELECTED=$(dialog --cr-wrap --stdout --backtitle "$BT" \
+ --title " $_EditTitle " --default-item $SELECTED --menu "$_EditBody" 0 0 0 \
+ "1" "$exitstr" "2" "Keyboard" "3" "Locale" "4" "Hostname" \
+ "5" "Sudoers" "6" "Mkinitcpio.conf" "7" "Fstab" "8" "Crypttab" \
+ "9" "${BOOTLDR^}" "10" "Pacman.conf" "11" "${LOGIN_TYPE^}")
+
+ if [[ ! $SELECTED || $SELECTED -eq 1 ]]; then
+ [[ $DEBUG == true ]] && more $DEBUG
+ # when die() is passed 127 as the exit code it will issue `systemctl -i reboot`
+ die 127
+ else
+ local existing_files=""
+ for f in $(printf "%s" "${EDIT_FILES[$SELECTED]}"); do
+ [[ -e ${MNT}$f ]] && existing_files+=" ${MNT}$f"
+ done
+ if [[ $existing_files ]]; then
+ if hash vim >/dev/null 2>&1; then
+ vim -O $existing_files
+ else
+ for f in $existing_files; do
+ if hash nano >/dev/null 2>&1; then nano $f; else vi $f; fi
+ done
+ fi
+ else
+ msgbox "$_ErrTitle" "$_NoFileErr"
+ fi
+ fi
+ edit_system_configs
+}
+
diff --git a/src/lib/install.sh b/src/lib/install.sh
index 323c46c..ae1541d 100644
--- a/src/lib/install.sh
+++ b/src/lib/install.sh
@@ -6,8 +6,6 @@
# this file is not meant to be run directly
# sourcing this file in a non bash shell is not advised
-# set -n
-
readonly RUN="/run/archiso/bootmnt/arch/boot"
readonly VM="$(dmesg | grep -i "hypervisor")"
@@ -232,12 +230,10 @@ mirrorlist_sort() {
printf "\n\n%s\n\n" "Sorting the mirrorlist"
if hash reflector >/dev/null 2>&1; then
$MIRROR_CMD --save $MNT/etc/pacman.d/mirrorlist --verbose ||
- reflector --score 100 -l 50 -f 10 \
- --sort rate --verbose --save $MNT/etc/pacman.d/mirrorlist
+ reflector --score 100 -l 50 -f 10 --sort rate --verbose --save $MNT/etc/pacman.d/mirrorlist
else
{ eval $MIRROR_CMD || curl -s 'https://www.archlinux.org/mirrorlist/all/'; } |
- sed -e 's/^#Server/Server/' -e '/^#/d' |
- rankmirrors -n 10 - > $MNT/etc/pacman.d/mirrorlist
+ sed -e 's/^#Server/Server/' -e '/^#/d' | rankmirrors -n 10 - > $MNT/etc/pacman.d/mirrorlist
fi
}
@@ -288,3 +284,4 @@ suckless_install() {
printf "\n\n%s\n\n" "To configure dwm edit /home/$NEWUSER/suckless/dwm/config.h and recompile with 'sudo make clean install'"
sleep 2
}
+
diff --git a/src/lib/luks.sh b/src/lib/luks.sh
index 6f33f10..8f43f81 100644
--- a/src/lib/luks.sh
+++ b/src/lib/luks.sh
@@ -7,7 +7,6 @@
# sourcing this file in a non bash shell is not advised
# shellcheck disable=2154
-# set -n
declare -g LUKS=""
declare -gx LUKS_DEV=""
diff --git a/src/lib/lvm.sh b/src/lib/lvm.sh
index 5a074f8..76c89a0 100644
--- a/src/lib/lvm.sh
+++ b/src/lib/lvm.sh
@@ -7,7 +7,6 @@
# sourcing this file in a non bash shell is not advised
# shellcheck disable=2154
-# set -n
declare -g LVM=""
declare -g VOL_GROUP_MB=0
diff --git a/src/lib/mount.sh b/src/lib/mount.sh
index fa16740..03d1acf 100644
--- a/src/lib/mount.sh
+++ b/src/lib/mount.sh
@@ -7,7 +7,6 @@
# sourcing this file in a non bash shell is not advised
# shellcheck disable=2154,2153,2046
-# set -n
readonly SYS_MEM="$(awk '/MemTotal/ {print int($2 / 1024)"M"}' /proc/meminfo)"
readonly SALT="$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32 | head -n 1)"
diff --git a/src/lib/package.sh b/src/lib/package.sh
new file mode 100644
index 0000000..dced077
--- /dev/null
+++ b/src/lib/package.sh
@@ -0,0 +1,129 @@
+#!/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,2153,2046
+
+select_browsers() {
+ local pkgs=""
+ pkgs="$(checkbox "$_Packages" "$_PackageBody" 0 0 0 \
+ "firefox" "A popular open-source graphical web browser from Mozilla" off \
+ "chromium" "an open-source graphical web browser based on the Blink rendering engine" off \
+ "opera" "Fast and secure, free of charge web browser from Opera Software" off \
+ "epiphany" "A GNOME web browser based on the WebKit rendering engine" off \
+ "qutebrowser" "A keyboard-focused vim-like web browser based on Python and PyQt5" off)"
+ printf "%s" "$pkgs"
+}
+
+select_editors() {
+ local pkgs=""
+ pkgs="$(checkbox "$_Packages" "$_PackageBody" 0 0 0 \
+ "atom" "An open-source text editor developed by GitHub that is licensed under the MIT License" off \
+ "geany" "A fast and lightweight IDE" off \
+ "emacs" "An extensible, customizable, self-documenting real-time display editor" off \
+ "neovim" "A fork of Vim aiming to improve user experience, plugins, and GUIs." off \
+ "mousepad" "A simple text editor" off)"
+ printf "%s" "$pkgs"
+}
+
+select_terminals() {
+ local pkgs=""
+ pkgs="$(checkbox "$_Packages" "$_PackageBody" 0 0 0 \
+ "termite" "A minimal VTE-based terminal emulator" off \
+ "rxvt-unicode" "A unicode enabled rxvt-clone terminal emulator" off \
+ "terminator" "Terminal emulator that supports tabs and grids" off \
+ "tilix" "A tiling terminal emulator for Linux using GTK+ 3" off \
+ "tilda" "A Gtk based drop down terminal for Linux and Unix" off \
+ "xfce4-terminal" "A terminal emulator based in the Xfce Desktop Environment" off)"
+ printf "%s" "$pkgs"
+}
+
+select_music_and_video() {
+ local pkgs=""
+ pkgs="$(checkbox "$_Packages" "$_PackageBody" 0 0 0 \
+ "vlc" "A free and open source cross-platform multimedia player" off \
+ "mpd" "A flexible, powerful, server-side application for playing music" off \
+ "ncmpcpp" "An mpd client and almost exact clone of ncmpc with some new features" off \
+ "cmus" "A small, fast and powerful console music player for Unix-like operating systems" off \
+ "audacious" "A free and advanced audio player based on GTK+" off \
+ "nicotine+" "A graphical client for Soulseek" off \
+ "lollypop" "A new music playing application" off \
+ "rhythmbox" "Music playback and management application" off \
+ "deadbeef" "A GTK+ audio player for GNU/Linux" off \
+ "clementine" "A modern music player and library organizer" off)"
+ printf "%s" "$pkgs"
+}
+
+select_mail_and_chat() {
+ local pkgs=""
+ pkgs="$(checkbox "$_Packages" "$_PackageBody" 0 0 0 \
+ "thunderbird" "Standalone mail and news reader from mozilla" off \
+ "geary" "A lightweight email client for the GNOME desktop" off \
+ "evolution" "Manage your email, contacts and schedule" off \
+ "mutt" "Small but very powerful text-based mail client" off \
+ "hexchat" "A popular and easy to use graphical IRC client" off \
+ "pidgin" "Multi-protocol instant messaging client" off \
+ "weechat" "Fast, light and extensible IRC client" off \
+ "irssi" "Modular text mode IRC client" off)"
+ printf "%s" "$pkgs"
+}
+
+select_office_and_editing() {
+ local pkgs=""
+ pkgs="$(checkbox "$_Packages" "$_PackageBody" 0 0 0 \
+ "libreoffice-fresh" "Full featured office suite" off \
+ "abiword" "Fully-featured word processor" off \
+ "calligra" "A set of applications for productivity" off \
+ "gimp" "GNU Image Manipulation Program" off \
+ "inkscape" "Professional vector graphics editor" off \
+ "krita" "Edit and paint images" off \
+ "obs-studio" "Free opensource streaming/recording software" off \
+ "openshot" "An open-source, non-linear video editor for Linux based on MLT framework" off \
+ "kdenlive" "A non-linear video editor for Linux using the MLT video framework" off \
+ "audacity" "A program that lets you manipulate digital audio waveforms" off \
+ "guvcview" "Capture video from camera devices" off \
+ "simplescreenrecorder" "A feature-rich screen recorder" off)"
+ printf "%s" "$pkgs"
+}
+
+select_managment() {
+ local pkgs=""
+ pkgs="$(checkbox "$_Packages" "$_PackageBody" 0 0 0 \
+ "thunar" "A modern file manager for the Xfce Desktop Environment" off \
+ "pcmanfm" "A fast and lightweight file manager based in Lxde" off \
+ "gnome-disk-utility" "Disk Management Utility" off \
+ "gnome-system-monitor" "View current processes and monitor system state" off \
+ "qt5ct" "GUI for managing Qt based application themes, icons, and fonts" off \
+ "ttf-hack" "A hand groomed and optically balanced typeface based on Bitstream Vera Mono" off \
+ "ttf-anonymous-pro" "A family of four fixed-width fonts designed especially with coding in mind" off \
+ "ttf-font-awesome" "Iconic font designed for Bootstrap" off \
+ "ttf-fira-code" "Monospaced font with programming ligatures" off \
+ "noto-fonts" "Google Noto fonts" off \
+ "noto-fonts-cjk" "Google Noto CJK fonts (Chinese, Japanese, Korean)" off)"
+ printf "%s" "$pkgs"
+}
+
+select_extra() {
+ local pkgs=""
+ pkgs="$(checkbox "$_Packages" "$_PackageBody" 0 0 0 \
+ "steam" "A popular game distribution platform by Valve" off \
+ "deluge" "A BitTorrent client written in python" off \
+ "transmission-gtk" "Free BitTorrent client GTK+ GUI" off \
+ "qbittorrent" "An advanced BitTorrent client" off \
+ "evince" "A document viewer" off \
+ "zathura" "Minimalistic document viewer" off \
+ "qpdfview" "A tabbed PDF viewer" off \
+ "mupdf" "Lightweight PDF and XPS viewer" off \
+ "gpicview" "Lightweight image viewer" off \
+ "gpick" "Advanced color picker using GTK+ toolkit" off \
+ "gcolor2" "A simple GTK+2 color selector" off \
+ "plank" "An elegant, simple, and clean dock" off \
+ "docky" "Full fledged dock that makes opening applications and managing windows faster and easier" off \
+ "cairo-dock" "Light eye-candy fully themable animated dock" off)"
+ printf "%s" "$pkgs"
+}
+
diff --git a/src/lib/part.sh b/src/lib/part.sh
index 9650f73..809348c 100644
--- a/src/lib/part.sh
+++ b/src/lib/part.sh
@@ -7,7 +7,6 @@
# sourcing this file in a non bash shell is not advised
# shellcheck disable=2154,2153,2046
-# set -n
declare -Agr FS_CMDS=(
[ext2]="mkfs.ext2 -q" [ext3]="mkfs.ext3 -q" [ext4]="mkfs.ext4 -q"
diff --git a/src/lib/utils.sh b/src/lib/utils.sh
index fac6351..11eb02e 100644
--- a/src/lib/utils.sh
+++ b/src/lib/utils.sh
@@ -7,21 +7,25 @@
# sourcing this file in a non bash shell is not advised
# shellcheck disable=2154
-# set -n
chrun() {
+ # run a shell command in the chroot dir $MNT
arch-chroot $MNT /bin/bash -c "$1"
}
json() {
+ # get a value from http://api.ipstack.com in json format using my API key
+ # this includes: ip, geolocation, country name
curl -s "http://api.ipstack.com/$2" | python3 -c "import sys, json; print(json.load(sys.stdin)['$1'])"
}
src() {
+ # source a file ($1), if it fails we die with an error message
. "$1" || { printf "\nFailed to source file %s\n" "$1"; die 1; }
}
ssd() {
+ # returns 0 (true) when the device passed ($1) is NOT a rotational device
local dev=$1
dev=${dev#/dev/}
[[ $dev =~ nvme ]] && dev=${dev%p[0-9]*} || dev=${dev%[0-9]*}
@@ -29,13 +33,16 @@ ssd() {
}
die() {
+ # die peacefully
local exitcode=0
(( $# == 0 )) || exitcode=$1
tput cnorm
if [[ -d $MNT ]] && cd; then
+ # use `fuser` to kill processes using the mounted directory before umounting it
fuser -km $MNT
umount_dir $MNT
+ # when passed 127 as the exit code, kill the loop mount to avoid hangups and reboot the system
if [[ $exitcode -eq 127 ]]; then
fuser -km /run/archiso/bootmnt
umount -l /run/archiso/bootmnt
@@ -46,51 +53,13 @@ die() {
}
sigint() {
+ # used to trap SIGINT and cleanly exit the program
printf "\n** CTRL-C caught"
die 1
}
-msgbox() {
- tput civis
- dialog --cr-wrap --backtitle "$BT" --title " $1 " --msgbox "$2\n" 0 0
-}
-
-menubox() {
- local title="$1"
- local body="$2"
- local h=$3
- local w=$4
- local n=$5
- shift 5
- if ! response="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $title " --menu "$body" $h $w $n "$@")"; then
- return 1
- fi
- printf "%s\n" "$response"
-}
-
-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() {
+print4() {
+ # takes an arbitrary number of input fields and prints them out in fourths on separate lines
local str="$*"
if [[ ${#str} -gt $(( ${COLUMNS:-$(tput cols)} / 2 )) ]]; then
q=$(awk '{print int(NF / 4)}' <<< "$str")
@@ -118,7 +87,14 @@ printq() {
printf "%s\n" "$str"
}
-devices() {
+oneshot() {
+ [[ -e /tmp/.ai_$1 || ! $(type $1) ]] && return 0
+ $1 || return 1
+ touch "/tmp/.ai_$1"
+ return 0
+}
+
+system_devices() {
IGNORE_DEV="$(lsblk -lno NAME,MOUNTPOINT | awk '/\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')"
if [[ $IGNORE_DEV ]]; then
SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE | awk '/disk/ && !'"/$IGNORE_DEV/"' {print "/dev/" $1 " " $2}')"
@@ -129,7 +105,7 @@ devices() {
declare -grx SYS_DEVS IGNORE_DEV DEV_COUNT
}
-sysid() {
+system_identify() {
declare -g IS_64BIT=false
local efidir="/sys/firmware/efi"
@@ -157,7 +133,7 @@ sysid() {
return 0
}
-checks() {
+system_checks() {
[[ $(whoami) == "root" ]] || { infobox "$_ErrTitle" "$_NotRoot\n$_Exit" && die 1; }
grep -qw 'lm' /proc/cpuinfo || { infobox "$_ErrTitle" "$_Not64Bit\n$_Exit" && die 1; }
@@ -176,6 +152,14 @@ checks() {
return 0
}
+preinstall_checks() {
+ [[ $(lsblk -o MOUNTPOINT) =~ $MNT ]] || { msgbox "$_ErrTitle" "$_ErrNoMount"; export SELECTED=4; return 1; }
+ if [[ $# -eq 1 ]]; then
+ [[ $CONFIG_DONE == true ]] || { msgbox "$_ErrTitle" "$_ErrNoConfig"; export SELECTED=5; return 1; }
+ fi
+ return 0
+}
+
echeck() {
# return if the last process exited normally
local last_exit_code=$?
@@ -198,29 +182,6 @@ echeck() {
return 0
}
-icheck() {
- [[ $(lsblk -o MOUNTPOINT) =~ $MNT ]] || { msgbox "$_ErrTitle" "$_ErrNoMount"; export SELECTED=4; return 1; }
- if [[ $# -eq 1 ]]; then
- [[ $CONFIG_DONE == true ]] || { msgbox "$_ErrTitle" "$_ErrNoConfig"; export SELECTED=5; return 1; }
- fi
- return 0
-}
-
-yesno() {
- # usage: yesno [ []]
- # 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>| $DBG