From 1e6f7a14384261105f9e5cf6f5c4e33049bb515f Mon Sep 17 00:00:00 2001 From: natemaia Date: Fri, 18 Jan 2019 23:18:58 -0800 Subject: [PATCH] Fix: error in package_operation() where two package names wouldn't be space separated --- lang/english.trans | 14 +- src/archlabs-installer | 384 +++++++++++++++++++++-------------------- 2 files changed, 205 insertions(+), 193 deletions(-) diff --git a/lang/english.trans b/lang/english.trans index 974029e..ed2adc5 100644 --- a/lang/english.trans +++ b/lang/english.trans @@ -49,8 +49,8 @@ _CloseInstBody="\nUnmount partitions (if any) and exit the installer?\n" # timezone _TimeZTitle="Timezone" _TimeZQ="\nConfirm time zone:" -_TimeSubZBody="\nSelect the nearest city to you or one with the same time zone.\n\nTIP: Pressing the first letter of the city name repeatedly will navigate between entries beggining with that letter." _TimeZBody="\nThe time zone is used to set the system clock.\n\nSelect your country or continent from the list below" +_TimeSubZBody="\nSelect the nearest city to you or one with the same time zone.\n\nTIP: Pressing the first letter of the city name repeatedly will navigate between entries beggining with that letter." # bootloader _MntBootBody="\nSelect which bootloader to use." @@ -101,7 +101,7 @@ _MntFail="\nMount Failed!\n" _MntSucc="\nMount Succeeded!\n" _MntConfBody="\nConfirm mount options:" _MntBody="\nUse [Space] to toggle mount options from below, press [Enter] when done to confirm selection.\n\nNot selecting any and confirming will run an automatic mount." -_WarnMount="\nIMPORTANT: Please choose carefully during mounting and formatting.\n\nDuring mounting, partitions can be mounted without formatting by selecting '$_Skip'.\nThis can be useful for data partitions or partitions you've already formatted.\n\nThe one exception is the root (/) partition, it needs to be formatted before install to ensure the system stability.\n" +_WarnMount="\nIMPORTANT: Please choose carefully during mounting and formatting.\n\nDuring mounting, partitions can be mounted without formatting by selecting '$_Skip', useful for extra or already formatted partitions.\n\nThe exception to this is the root (/) partition, it needs to be formatted before install to ensure system stability.\n" # Select Device _DevSelTitle="Device Selection" @@ -138,7 +138,7 @@ _InstSysBody="\nInstall syslinux to the master boot record (MBR) or to root (/)? # File System _FSTitle="Choose Filesystem" -_SelRootBody="\nSelect root (/) partition.\n\nThis is the partition where $DIST will be installed." +_SelRootBody="\nSelect the system root (/) partition.\n\nThis is where $DIST will be installed." _SelBiosBody="\nDo you want to use a separate boot partition? (required for LUKS)\n\nThis partition is where the bootloader will be installed.\n" _SelSwpNone="None" @@ -146,7 +146,7 @@ _SelSwpFile="Swapfile" _SelSwpSetup="Swap Setup" _SelSwpBody="\nSelect whether to use a swap partition, swapfile, or none." _SelSwpErr="Swap Setup Error: Must be 1(M|G) or greater, and can only contain whole numbers\n\nSize Entered:" -_SelSwpSize="\nEnter the size to use for swap in MB or GB.\n\nFor ease of use and as an example the size has been filled in to the size of your system memory (RAM).\n\nMust be greater than 1, end in either M or G, and contain only whole numbers." +_SelSwpSize="\n\n\nEnter the size of the swapfile in megabytes (M) or gigabytes (G).\n\neg. 100M will create a 100 megabyte swapfile, while 10G will create a 10 gigabyte swapfile.\n\nFor ease of use and as an example the size has been filled in to the size of your system memory (RAM).\n\nMust be greater than 1, end in either M or G, and contain only whole numbers." _SelUefiBody="\nSelect the system EFI boot partition.\n\nThis is a required partition for booting UEFI systems. It's usually the first partition on the drive, less than 512M, and will be formatted as vfat/fat32 if not already." _FormUefiBody="\nIMPORTANT: The EFI partition" @@ -159,12 +159,12 @@ _LuksMenuBody="\nDevices and volumes encrypted using dm_crypt cannot be accessed _LuksMenuBody2="\n\nA seperate boot partition without encryption or logical volume management (LVM - unless using BIOS Grub) is required." _LuksMenuBody3="\n\nAutomatic uses default encryption settings, and is recommended for beginners, otherwise cypher and key size parameters may be entered manually." _LuksOpen="Open Encrypted Partition" -_LuksOpenBody="Enter a name and password for the encrypted device.\n\nIt is not necessary to prefix it with /dev/mapper/.\n\nAn example name has been provided." +_LuksOpenBody="Enter a name and password for the encrypted device.\n\nIt is not necessary to prefix it with /dev/mapper/\n\nAn example name has been provided." _LuksEncrypt="Automatic LUKS Encryption" _LuksEncryptAdv="Define Key-Size and Cypher" _LuksEncryptBody="\nSelect the partition you want to encrypt." _LuksEncryptSucc="\nDone! encrypted partition opened and ready for mounting.\n" -_LuksPartErrBody="\nA minimum of two partitions are required for encryption:\n\n1. Root (/) - standard or LVM.\n\n2. Boot (/boot or /boot/efi) - standard (except for LVM on BIOS systems)." +_LuksPartErrBody="\nA minimum of two partitions are required for encryption:\n\n1. root (/) - standard or LVM.\n\n2. boot (/boot or /boot/efi) - standard (except for LVM on BIOS systems)." _LuksCreateWaitBody="\nCreating encrypted partition:" _LuksOpenWaitBody="\nOpening encrypted partition:" _LuksWaitBody2="\n\nDevice or volume used:" @@ -188,7 +188,7 @@ _LvmLvNumBody2="\nThe last (or only) logical volume will automatically use all r _LvmLvNameBody1="Enter the name of the logical volume (LV) to create.\n\nThis is like setting a name or label for a partition.\n" _LvmLvNameBody2="\nNOTE: This logical volume will use up all remaining space in the volume group" _LvmLvSizeBody1="remaining" -_LvmLvSizeBody2="\n\nEnter the size of the logical volume (LV) in megabytes (M) or gigabytes (G). For example, 100M will create a 100 megabyte LV. 10G will create a 10 Gigabyte LV.\n" +_LvmLvSizeBody2="\n\nEnter the size of the logical volume (LV) in megabytes (M) or gigabytes (G). For example, 100M will create a 100 megabyte LV. 10G will create a 10 gigabyte LV.\n" _LvmCompBody="\nDone! all logical volumes have been created for the volume group.\n\nDo you want to view the device tree for the new LVM scheme?\n" _LvmDelQ="\nConfirm deletion of volume group(s) and logical volume(s).\n\nDeleting a volume group, will delete all logical volumes within as well." _LvmSelVGBody="Select volume group to delete.\n\nAll logical volumes within will also be deleted." diff --git a/src/archlabs-installer b/src/archlabs-installer index 9884b77..3e5be0c 100755 --- a/src/archlabs-installer +++ b/src/archlabs-installer @@ -5,13 +5,15 @@ # 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 +# Some ideas and code reworked from other resources +# AIF, Cnichi, Calamares, Arch Wiki.. Credit where credit is due -VER="1.8.39" # version +VER="1.8.42" # version DIST="ArchLabs" # distributor MNT="/mnt" # install mountpoint +# set -n + # bulk default values { ROOT_PART="" # root partition @@ -28,11 +30,11 @@ ROOT_PASS="" # root password LOGIN_WM="" # default login session LOGIN_TYPE="" # login manager can be lightdm or xinit INSTALL_WMS="" # space separated list of chosen wm/de -KERNEL="" # kernel can be linux or linux-lts +KERNEL="linux" # kernel can be linux or linux-lts +MYSHELL="" # login shell for root and the primary user PACKAGES="" # list of all packages to install including WM_PACKAGES USER_PKGS="" # packages selected by the user during install WM_PACKAGES="" # full list of packages added during wm/de choice -MYSHELL="" # login shell for root and the primary user UCODE="" # cpu manufacturer microcode filename (if any) HOOKS="shutdown" # list of additional HOOKS to add in /etc/mkinitcpio.conf FONT="ter-i16n" # font used in the linux console @@ -55,6 +57,9 @@ CONFIG_DONE=false # basic configuration is finished BROADCOM_WL=false # fixes for broadcom cards eg. BCM4352 CHECKED_NET=false # have we checked the network connection already +AUTO_ROOT_PART="" # values from auto partition +AUTO_BOOT_PART="" + # sane baseline BASE_PKGS="archlabs-scripts archlabs-skel-base archlabs-themes archlabs-dARK archlabs-icons archlabs-wallpapers " BASE_PKGS+="base-devel xorg xorg-drivers sudo git gvfs gtk3 gtk-engines gtk-engine-murrine pavucontrol tumbler " @@ -64,15 +69,12 @@ BASE_PKGS+="playerctl ffmpeg gstreamer libmad libmatroska gst-libav gst-plugins- WM_BASE_PKGS="arandr archlabs-networkmanager-dmenu xdg-user-dirs nitrogen polkit-gnome volumeicon xclip exo " WM_BASE_PKGS+="xdotool compton gnome-keyring dunst feh gsimplecal xfce4-power-manager xfce4-settings laptop-detect" +SEL=0 # currently selected menu item ERR="/tmp/errlog" # error log used internally DBG="/tmp/debuglog" # debug log when passed -d RUN="/run/archiso/bootmnt/arch/boot" # path for live /boot BT="$DIST Installer - v$VER" # backtitle used for dialogs VM="$(dmesg | grep -i "hypervisor")" # is the system a vm -SEL=0 # currently selected menu item - -AUTO_ROOT_PART="" # values from auto partition -AUTO_BOOT_PART="" # } @@ -237,10 +239,10 @@ main() case $SEL in 1) device_tree ;; - 2) partition || (( SEL-- )) ;; + 2) partition_menu || (( SEL-- )) ;; 3) luks_menu || (( SEL-- )) ;; 4) lvm_menu || (( SEL-- )) ;; - 5) mnt_menu || (( SEL-- )) ;; + 5) mounting_menu || (( SEL-- )) ;; 6) prechecks 0 && { mkuser || (( SEL-- )); } ;; 7) prechecks 1 && { cfg_menu || (( SEL-- )); } ;; 8) prechecks 2 && { select_sessions || (( SEL-- )); } ;; @@ -343,49 +345,49 @@ cfg_menu() mkuser() { - tput cnorm - local values - if ! values="$(dialog --stdout --no-cancel --separator ';:~:;' \ - --ok-label "Submit" --backtitle "$BT" --title " $_UserTitle " \ - --insecure --mixedform "$_UserBody" 0 0 0 \ - "$_Username" 1 1 "$NEWUSER" 1 $((${#_Username} + 2)) $COLUMNS 0 0 \ - "$_Password" 2 1 "" 2 $((${#_Password} + 2)) $COLUMNS 0 1 \ - "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) $COLUMNS 0 1 \ - "$_RootBody" 6 1 "" 6 $((${#_RootBody} + 1)) $COLUMNS 0 2 \ - "$_Password" 8 1 "" 8 $((${#_Password} + 2)) $COLUMNS 0 1 \ - "$_Password2" 9 1 "" 9 $((${#_Password2} + 2)) $COLUMNS 0 1)"; then - return 1 - fi + local values="" user="" pass="" pass2="" rpass="" rpass2="" err=0 - local user pass pass2 rpass rpass2 - user="$(awk -F';:~:;' '{print $1}' <<< "$values")" - pass="$(awk -F';:~:;' '{print $2}' <<< "$values")" - pass2="$(awk -F';:~:;' '{print $3}' <<< "$values")" - rpass="$(awk -F';:~:;' '{print $5}' <<< "$values")" - rpass2="$(awk -F';:~:;' '{print $6}' <<< "$values")" + while true; do + tput cnorm + values="$(dialog --stdout --no-cancel --separator ';:~:;' \ + --ok-label "Submit" --backtitle "$BT" --title " $_UserTitle " \ + --insecure --mixedform "$_UserBody" 0 0 0 \ + "$_Username" 1 1 "$user" 1 $((${#_Username} + 2)) $COLUMNS 0 0 \ + "$_Password" 2 1 "" 2 $((${#_Password} + 2)) $COLUMNS 0 1 \ + "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) $COLUMNS 0 1 \ + "$_RootBody" 6 1 "" 6 $((${#_RootBody} + 1)) $COLUMNS 0 2 \ + "$_Password" 8 1 "" 8 $((${#_Password} + 2)) $COLUMNS 0 1 \ + "$_Password2" 9 1 "" 9 $((${#_Password2} + 2)) $COLUMNS 0 1)" - # both root passwords are empty, so use the user passwords instead - [[ $rpass == "" && $rpass2 == "" ]] && { rpass="$pass"; rpass2="$pass2"; } + err=$? + (( err == 0 )) || break - # make sure a username was entered and that the passwords match - if [[ ${#user} -eq 0 || $user =~ \ |\' || $user =~ [^a-z0-9] ]]; then - msgbox "$_UserErrTitle" "$_UserErrBody" - mkuser || return 1 - elif [[ $pass == "" ]]; then - msgbox "$_ErrTitle" "$_UserPassEmpty\n$_TryAgain" - mkuser || return 1 - elif [[ "$pass" != "$pass2" ]]; then - msgbox "$_ErrTitle" "$_UserPassErr\n$_TryAgain" - mkuser || return 1 - elif [[ "$rpass" != "$rpass2" ]]; then - msgbox "$_ErrTitle" "$_RootPassErr\n$_TryAgain" - mkuser || return 1 - fi + user="$(awk -F';:~:;' '{print $1}' <<< "$values")" + pass="$(awk -F';:~:;' '{print $2}' <<< "$values")" + pass2="$(awk -F';:~:;' '{print $3}' <<< "$values")" + rpass="$(awk -F';:~:;' '{print $5}' <<< "$values")" + rpass2="$(awk -F';:~:;' '{print $6}' <<< "$values")" - NEWUSER="$user" - USER_PASS="$pass" - ROOT_PASS="$rpass" - return 0 + # root passwords empty, so use the user passwords + [[ $rpass == "" && $rpass2 == "" ]] && { rpass="$pass"; rpass2="$pass2"; } + + # make sure a username was entered and that the passwords match + if [[ ${#user} -eq 0 || $user =~ \ |\' || $user =~ [^a-z0-9] ]]; then + msgbox "$_UserErrTitle" "$_UserErrBody"; user="" + elif [[ $pass == "" ]]; then + msgbox "$_ErrTitle" "$_UserPassEmpty\n$_TryAgain" + elif [[ "$pass" != "$pass2" ]]; then + msgbox "$_ErrTitle" "$_UserPassErr\n$_TryAgain" + elif [[ "$rpass" != "$rpass2" ]]; then + msgbox "$_ErrTitle" "$_RootPassErr\n$_TryAgain" + else + NEWUSER="$user" + USER_PASS="$pass" + ROOT_PASS="$rpass" + break + fi + done + return $err } select_keymap() @@ -447,16 +449,16 @@ select_timezone() if ! ZONE="$(menubox "$_TimeZTitle" "$_TimeZBody" \ 'America' '-' 'Australia' '-' 'Asia' '-' 'Atlantic' '-' 'Africa' '-' \ 'Europe' '-' 'Indian' '-' 'Pacific' '-' 'Arctic' '-' 'Antarctica' '-')"; then - return 1 - fi + return 1 + fi - if ! SUBZONE="$(dialog --cr-wrap --stdout --backtitle "$BT" \ - --title " $_TimeZTitle " --menu "$_TimeSubZBody" 0 0 $((LINES - 17)) ${SUBZONES[$ZONE]})"; then - return 1 - fi + if ! SUBZONE="$(dialog --cr-wrap --stdout --backtitle "$BT" \ + --title " $_TimeZTitle " --menu "$_TimeSubZBody" 0 0 $((LINES - 17)) ${SUBZONES[$ZONE]})"; then + return 1 + fi - yesno "$_TimeZTitle" "$_TimeZQ $ZONE/$SUBZONE?\n" || select_timezone -} + yesno "$_TimeZTitle" "$_TimeZQ $ZONE/$SUBZONE?\n" || select_timezone + } select_sessions() { @@ -613,7 +615,8 @@ edit_configs() select_packages() { - local cur=0 + local cur=0 b="" e="" f="" t="" m="" ml="" p="" v="" fn="" to="" s="" x="" + while true; do (( cur < 13 )) && (( cur++ )) @@ -638,25 +641,23 @@ select_packages() [[ $cur && $cur -lt 13 ]] || break case $cur in - 1) BROWSE_PKGS="$(select_browsers)" ;; - 2) EDIT_PKGS="$(select_editors)" ;; - 3) FM_PKGS="$(select_files)" ;; - 4) TERM_PKGS="$(select_terms)" ;; - 5) MEDIA_PKGS="$(select_media)" ;; - 6) MAIL_PKGS="$(select_mail)" ;; - 7) PROF_PKGS="$(select_prof)" ;; - 8) VIEW_PKGS="$(select_viewers)" ;; - 9) FNT_PKGS="$(select_fonts)" ;; - 10) TOR_PKGS="$(select_torrent)" ;; - 11) SYS_PKGS="$(select_sys)" ;; - 12) EX_PKGS=" $(select_extra)" ;; + 1) b="$(pkg_browsers)" ;; + 2) e="$(pkg_editors)" ;; + 3) f="$(pkg_files)" ;; + 4) t="$(pkg_terms)" ;; + 5) m="$(pkg_media)" ;; + 6) ml="$(pkg_mail)" ;; + 7) p="$(pkg_prof)" ;; + 8) v="$(pkg_viewers)" ;; + 9) fn="$(pkg_fonts)" ;; + 10) to="$(pkg_torrent)" ;; + 11) s="$(pkg_sys)" ;; + 12) x="$(pkg_extra)" ;; esac - USER_PKGS="$BROWSE_PKGS $EDIT_PKGS $FM_PKGS $TERM_PKGS $MEDIA_PKGS $MAIL_PKGS " - USER_PKGS+="$PROF_PKGS $VIEW_PKGS $FNT_PKGS $TOR_PKGS $SYS_PKGS $EX_PKGS" - done - USER_PKGS="$BROWSE_PKGS $EDIT_PKGS $FM_PKGS $TERM_PKGS $MEDIA_PKGS $MAIL_PKGS " - USER_PKGS+="$PROF_PKGS $VIEW_PKGS $FNT_PKGS $TOR_PKGS $SYS_PKGS $EX_PKGS" + # add all to the user package list regardless of what was picked + USER_PKGS="$b $e $f $t $m $ml $p $v $fn $to $s $x" + done for i in $USER_PKGS; do [[ ${PKG_EXT[$i]} && $USER_PKGS != *"${PKG_EXT[$i]}"* ]] && USER_PKGS="${USER_PKGS% } ${PKG_EXT[$i]}" @@ -669,7 +670,7 @@ select_packages() return 0 } -select_browsers() +pkg_browsers() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -682,7 +683,7 @@ select_browsers() printf "%s" "$pkgs" } -select_editors() +pkg_editors() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -694,7 +695,7 @@ select_editors() printf "%s" "$pkgs" } -select_files() +pkg_files() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -707,7 +708,7 @@ select_files() printf "%s" "$pkgs" } -select_terms() +pkg_terms() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -723,7 +724,7 @@ select_terms() printf "%s" "$pkgs" } -select_media() +pkg_media() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -741,7 +742,7 @@ select_media() printf "%s" "$pkgs" } -select_mail() +pkg_mail() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -756,7 +757,7 @@ select_mail() printf "%s" "$pkgs" } -select_prof() +pkg_prof() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -775,7 +776,7 @@ select_prof() printf "%s" "$pkgs" } -select_fonts() +pkg_fonts() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -788,7 +789,7 @@ select_fonts() printf "%s" "$pkgs" } -select_viewers() +pkg_viewers() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -800,7 +801,7 @@ select_viewers() printf "%s" "$pkgs" } -select_torrent() +pkg_torrent() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -812,7 +813,7 @@ select_torrent() printf "%s" "$pkgs" } -select_sys() +pkg_sys() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -822,7 +823,7 @@ select_sys() printf "%s" "$pkgs" } -select_extra() +pkg_extra() { local pkgs="" pkgs="$(checkbox "$_Packages" "$_PackageBody" \ @@ -838,25 +839,18 @@ select_extra() ############################################################################### # partition menus -format() +partition_menu() { - infobox "$_FSTitle" "\nRunning: ${FS_CMDS[$2]} $1\n" 1 - ${FS_CMDS[$2]} "$1" >/dev/null 2>$ERR - errshow "${FS_CMDS[$2]} $1" -} + local device choice -partition() -{ - local device - if [[ $# -eq 0 ]]; then + if [[ $# -eq 1 ]]; then + device="$1" + else select_device 'root' || return 1 device="$DEVICE" - else - device="$1" fi tput civis - local choice if [[ $DISPLAY ]] && hash gparted >/dev/null 2>&1; then choice="$(menubox "$_PartTitle" "$_PartBody" \ "$_PartShowTree" "Shows output from the lsblk command" \ @@ -882,13 +876,13 @@ partition() if [[ $choice == "$_Done" || $choice == "" ]]; then return 0 elif [[ $choice != "$_PartWipe" && $choice != "$_PartAuto" && $choice != "$_PartShowTree" ]]; then - clear; tput cnorm; $choice "$device"; partition "$device" + clear; tput cnorm; $choice "$device"; partition_menu "$device" elif [[ $choice == "$_PartShowTree" ]]; then msgbox "$_PartTitle" "\n\n$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE,MOUNTPOINT "$device")\n\n" - partition "$device" + partition_menu "$device" elif [[ $choice == "$_PartWipe" ]]; then yesno "$_PartWipe" "$_PartBody1 $device $_PartWipeBody" && wipe -Ifrev $device - partition "$device" + partition_menu "$device" else local root_size msg ret table boot_fs root_size=$(lsblk -lno SIZE "$device" | awk 'NR == 1 { @@ -908,13 +902,20 @@ partition() if yesno "$_PrepParts" "$_PartBody1 $device $msg ($size)$_PartBody3"; then auto_partition "$device" "$table" "$boot_fs" "$root_size" || return 1 else - partition "$device" + partition_menu "$device" fi fi return 0 } +format_as() +{ + infobox "$_FSTitle" "\nRunning: ${FS_CMDS[$2]} $1\n" 1 + ${FS_CMDS[$2]} "$1" >/dev/null 2>$ERR + errshow "${FS_CMDS[$2]} $1" +} + decr_count() { # remove a partition from the dialog list and decrement the number partitions left @@ -1160,7 +1161,7 @@ setup_boot_device() ############################################################################### # mounting menus -mnt_menu() +mounting_menu() { # prepare partition list PARTS for dialog lvm_detect @@ -1196,7 +1197,7 @@ select_swap() if ! SWAP_SIZE="$(getinput "$_SelSwpSetup" "$_SelSwpSize" "$SYS_MEM")"; then SWAP_PART=""; SWAP_SIZE=""; break; return 0 fi - ((i++)) + (( i++ )) done enable_swap "$MNT/swapfile" SWAP_PART="/swapfile" @@ -1271,7 +1272,7 @@ select_filesystem() fi [[ $fs ]] || return 1 if yesno "$_FSTitle" "\nFormat $part as $fs?\n"; then - format "$part" "$fs" || return 1 + format_as "$part" "$fs" || return 1 else select_filesystem "$part" || return 1 fi @@ -1296,11 +1297,11 @@ select_efi_partition() if grep -q 'fat' <<< "$(fsck -N "$BOOT_PART")"; then local msg="$_FormUefiBody $BOOT_PART $_FormUefiBody2" if yesno "$_PrepMount" "$msg" "Format $BOOT_PART" "Skip Formatting" "no"; then - format "$BOOT_PART" "vfat" + format_as "$BOOT_PART" "vfat" sleep 1 fi else - format "$BOOT_PART" "vfat" + format_as "$BOOT_PART" "vfat" sleep 1 fi @@ -1321,11 +1322,11 @@ select_boot_partition() if grep -q 'ext[34]' <<< "$(fsck -N "$BOOT_PART")"; then local msg="$_FormBiosBody $BOOT_PART $_FormBiosBody2" if yesno "$_PrepMount" "$msg" "Format $BOOT_PART" "Skip Formatting" "no"; then - format "$BOOT_PART" "ext4" + format_as "$BOOT_PART" "ext4" sleep 1 fi else - format "$BOOT_PART" "ext4" + format_as "$BOOT_PART" "ext4" sleep 1 fi return 0 @@ -1348,22 +1349,20 @@ select_root_partition() select_extra_partitions() { + local part + while (( COUNT > 0 )); do tput civis - local part part="$(menubox "$_PrepMount " "$_ExtPartBody" "$_Done" "Return to the last menu" $PARTS)" if [[ $part == "$_Done" || $part == "" ]]; then break - elif ! select_filesystem "$part"; then - break; return 1 - elif ! select_mountpoint; then - break; return 1 - elif ! mount_partition "$part" "$EXTRA_MNT"; then + elif select_filesystem "$part" && select_mountpoint && mount_partition "$part" "$EXTRA_MNT"; then + EXTRA_MNTS="$EXTRA_MNTS $part: $EXTRA_MNT" + [[ $EXTRA_MNT == '/usr' && $HOOKS != *usr* ]] && HOOKS="usr $HOOKS" + else break; return 1 fi - EXTRA_MNTS="$EXTRA_MNTS $part: $EXTRA_MNT" - [[ $EXTRA_MNT == '/usr' && $HOOKS != *usr* ]] && HOOKS="usr $HOOKS" done return 0 @@ -1377,7 +1376,7 @@ install() clear tput cnorm install_base - printf "Generating system /etc/fstab\n" + printf "Generating /etc/fstab: genfstab -U $MNT >$MNT/etc/fstab\n" genfstab -U $MNT >$MNT/etc/fstab 2>$ERR errshow 1 "genfstab -U $MNT >$MNT/etc/fstab" [[ -f $MNT/swapfile ]] && sed -i "s~${MNT}~~" $MNT/etc/fstab @@ -1385,10 +1384,13 @@ install() package_operations run_mkinitcpio install_bootloader + printf "Setting hardware clock with: hwclock --systohc --utc\n" chrun "hwclock --systohc --utc" || chrun "hwclock --systohc --utc --directisa" create_user login_manager + printf "Setting ownership of /home/$NEWUSER\n" chrun "chown -Rf $NEWUSER:users /home/$NEWUSER" + sleep 3 edit_configs } @@ -1491,20 +1493,25 @@ EOF create_user() { - printf "Creating user $NEWUSER, setting passwords, and setting shell\n" - - chrun "chpasswd <<< 'root:$ROOT_PASS'" + printf "Setting root password\n" + chrun "chpasswd <<< 'root:$ROOT_PASS'" 2>$ERR + errshow 1 "set root password" if [[ $MYSHELL != *zsh ]]; then - chrun "usermod -s $MYSHELL root" + chrun "usermod -s $MYSHELL root" 2>$ERR + errshow 1 "usermod -s $MYSHELL root" if [[ $MYSHELL == "/usr/bin/mksh" ]]; then cp -fv $MNT/etc/skel/.mkshrc /root/.mkshrc fi fi + printf "Creating user $NEWUSER with: useradd -m -u 1000 -g users -G $groups -s $MYSHELL $NEWUSER\n" local groups='audio,autologin,floppy,log,network,rfkill,scanner,storage,optical,power,wheel' - chrun "groupadd -r autologin" - chrun "useradd -m -u 1000 -g users -G $groups -s $MYSHELL $NEWUSER" - chrun "chpasswd <<< '$NEWUSER:$USER_PASS'" + chrun "groupadd -r autologin" 2>$ERR + errshow 1 "groupadd -r autologin" + chrun "useradd -m -u 1000 -g users -G $groups -s $MYSHELL $NEWUSER" 2>$ERR + errshow 1 "useradd -m -u 1000 -g users -G $groups -s $MYSHELL $NEWUSER" + chrun "chpasswd <<< '$NEWUSER:$USER_PASS'" 2>$ERR + errshow 1 "set $NEWUSER password" if [[ $USER_PKGS == *neovim* ]]; then mkdir -p $MNT/home/$NEWUSER/.config/nvim @@ -1520,10 +1527,10 @@ create_user() setup_xinit() { - if [[ -e $MNT/home/$NEWUSER/.xinitrc ]]; then - sed -i "s/openbox-session/${LOGIN_WM}/g" $MNT/home/$NEWUSER/.xinitrc + if [[ -e $MNT/home/$NEWUSER/.xinitrc ]] && grep -q 'exec' $MNT/home/$NEWUSER/.xinitrc; then + sed -i "/exec/ c exec ${LOGIN_WM}" $MNT/home/$NEWUSER/.xinitrc else - printf "exec $LOGIN_WM\n" > $MNT/home/$NEWUSER/.xinitrc + printf "exec %s\n" "$LOGIN_WM" > $MNT/home/$NEWUSER/.xinitrc fi # automatic startx for login shells @@ -1660,13 +1667,13 @@ package_operations() [[ $MYSHELL == *mksh* ]] && inpkg+=" mksh" [[ $BOOTLDR == 'grub' ]] && inpkg+=" grub" [[ $KERNEL == 'linux-lts' ]] && { inpkg+=" linux-lts"; rmpkg+=" linux"; } - [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps|dwm) ]] && inpkg+="$WM_BASE_PKGS" + [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps|dwm) ]] && inpkg+=" $WM_BASE_PKGS" [[ $INSTALL_WMS =~ ^(plasma|gnome|cinnamon)$ ]] || inpkg+=" archlabs-ksuperkey" - chrun "pacman -Syyu --noconfirm" - chrun "pacman -Rns $rmpkg --noconfirm" - chrun "pacman -S iputils --noconfirm" - chrun "pacman -S $inpkg --needed --noconfirm" + chrun "pacman -Syyu --noconfirm" 2>/dev/null + chrun "pacman -Rns $rmpkg --noconfirm" 2>/dev/null + chrun "pacman -S iputils --noconfirm" 2>/dev/null + chrun "pacman -S $inpkg --needed --noconfirm" 2>/dev/null sed -i "s/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g" $MNT/etc/sudoers return 0 @@ -1686,10 +1693,10 @@ suckless_install() fi done - if [[ -d /home/$NEWUSER/suckless/dwm ]]; then + if [[ -d $MNT/home/$NEWUSER/suckless/dwm && -x $MNT/usr/bin/dwm ]]; then printf "To configure dwm edit /home/$NEWUSER/suckless/dwm/config.h\n" printf "You can then recompile it with 'sudo make clean install'\n" - sleep 2 + sleep 3 fi } @@ -1722,7 +1729,7 @@ setup_grub() BCMDS[grub]="${BCMDS[grub]} --target=i386-pc $BOOT_DEVICE" else if [[ $ROOT_PART == */dev/mapper/* && ! $LVM && ! $LUKS_PASS ]]; then - luks_pass "$_LuksOpen" "" || return 1 + luks_pass "$_LuksOpen" 1 || return 1 fi BCMDS[grub]="mount -t efivarfs efivarfs $efidir/efivars || true && ${BCMDS[grub]} --bootloader-id=$DIST" @@ -1863,7 +1870,7 @@ install_bootloader() fi if [[ $BOOTLDR != 'grub' ]]; then - rm -f $MNT/etc/default/grub 2>dev/null + rm -f $MNT/etc/default/grub 2>/dev/null find $MNT/boot/ -name 'grub*' -exec rm -rf '{}' \; >/dev/null 2>&1 fi @@ -1883,6 +1890,7 @@ install_bootloader() fi if [[ $BOOTLDR == 'grub' && $SYS == 'UEFI' ]]; then + printf "Copying grub efi stub to system fallback ${BMNTS[$SYS-$BOOTLDR]}/EFI/BOOT/BOOTX64.EFI\n" local esp="${MNT}${BMNTS[$SYS-$BOOTLDR]}" mkdir -pv $esp/EFI/BOOT cp -fv $esp/EFI/$DIST/grubx64.efi $esp/EFI/BOOT/BOOTX64.EFI @@ -2032,13 +2040,13 @@ lvm_extra_lvs() lvcreate -L "$VOLUME_SIZE" "$VOLUME_GROUP" -n "$VOLUME_NAME" >/dev/null 2>$ERR errshow "lvcreate -L $VOLUME_SIZE $VOLUME_GROUP -n $VOLUME_NAME" msgbox "$_LvmCreateVG (LV:$VOL_COUNT)" "$_Done LV $VOLUME_NAME ($VOLUME_SIZE) $_LvmPvDoneBody2." - ((VOL_COUNT--)) + (( VOL_COUNT-- )) done return 0 } -lvm_volume_count() +lvm_volumes() { VOL_COUNT=$(dialog --cr-wrap --no-cancel --stdout \ --backtitle "$BT" --title " $_LvmCreateVG " \ @@ -2061,7 +2069,7 @@ lvm_partitions() (( ${#LVM_PARTS[@]} >= 1 )) } -lvm_create_group() +lvm_mkgroup() { lvm_group_name || return 1 @@ -2091,7 +2099,6 @@ lvm_create_group() local msg="$_LvmPvDoneBody1 $VOLUME_GROUP ($GROUP_SIZE $GROUP_SIZE_TYPE)" msgbox "$_LvmCreateVG" "$msg $_LvmPvDoneBody2\n" - return 0 } lvm_create() @@ -2101,8 +2108,8 @@ lvm_create() VGROUP_MB=0 umount_dir $MNT lvm_partitions || return 1 - lvm_create_group || return 1 - lvm_volume_count || return 1 + lvm_mkgroup || return 1 + lvm_volumes || return 1 lvm_extra_lvs || return 1 lvm_volume_name "$_LvmLvNameBody1 $_LvmLvNameBody2 (${VGROUP_MB}MB)" || return 1 lvcreate -l +100%FREE "$VOLUME_GROUP" -n "$VOLUME_NAME" >/dev/null 2>$ERR @@ -2111,8 +2118,7 @@ lvm_create() tput civis sleep 0.5 local msg="${_Done}$_LvmPvDoneBody1 $VOLUME_GROUP-$VOLUME_NAME (${VOLUME_SIZE:-${VGROUP_MB}MB}) $_LvmPvDoneBody2." - msgbox "$_LvmCreateVG (LV:$VOL_COUNT)" "$msg\n$(lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE "${LVM_PARTS[@]}")" - return 0 + msgbox "$_LvmCreateVG (LV:$VOL_COUNT)" "$msg\n$(lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE "${LVM_PARTS[@]}")\n" } lvm_del_vg() @@ -2141,7 +2147,6 @@ lvm_del_all() done LVM='' fi - return 0 } @@ -2184,7 +2189,7 @@ luks_open() return 1 fi - luks_pass "$_LuksOpen" "${LUKS_NAME:-cryptroot}" || return 1 + luks_pass "$_LuksOpen" || return 1 infobox "$_LuksOpen" "$_LuksOpenWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0 cryptsetup open --type luks $LUKS_PART "$LUKS_NAME" <<< "$LUKS_PASS" 2>$ERR errshow "cryptsetup open --type luks $LUKS_PART $LUKS_NAME" @@ -2196,46 +2201,52 @@ luks_open() luks_pass() { - local title="$1" - local name="$2" - local pass pass2 - LUKS_PASS="" - LUKS_NAME="" + local title="$1" onlypass="$2" values="" pass="" pass2="" err=0 + + while true; do + tput cnorm + if [[ $onlypass ]]; then + values="$(dialog --stdout --no-cancel --separator ';:~:;' \ + --ok-label "Submit" --backtitle "$BT" --title " $title " --insecure --mixedform \ + "\nEnter the password to decrypt $ROOT_PART.\n\nThis is needed to create a keyfile." 0 0 0 \ + "$_Password" 1 1 "" 1 $((${#_Password} + 2)) $COLUMNS 0 1 \ + "$_Password2" 2 1 "" 2 $((${#_Password2} + 2)) $COLUMNS 0 1)" + + else + values="$(dialog --stdout --no-cancel --separator ';:~:;' \ + --ok-label "Submit" --backtitle "$BT" --title " $title " \ + --insecure --mixedform "$_LuksOpenBody" 0 0 0 \ + "$_Name" 1 1 "${LUKS_NAME:-cryptroot}" 1 $((${#_Name} + 2)) $COLUMNS 0 0 \ + "$_Password" 2 1 "" 2 $((${#_Password} + 2)) $COLUMNS 0 1 \ + "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) $COLUMNS 0 1)" - tput cnorm - local values - if [[ $name == "" ]]; then - if ! values="$(dialog --stdout --no-cancel --separator ';:~:;' \ - --ok-label "Submit" --backtitle "$BT" --title " $title " --insecure --mixedform \ - "\nEnter the password to decrypt $ROOT_PART.\n\nThis is needed to create a keyfile." 0 0 0 \ - "$_Password" 1 1 "" 1 $((${#_Password} + 2)) $COLUMNS 0 1 \ - "$_Password2" 2 1 "" 2 $((${#_Password2} + 2)) $COLUMNS 0 1)"; then - return 1 fi - pass="$(awk -F';:~:;' '{print $1}' <<< "$values")" - pass2="$(awk -F';:~:;' '{print $2}' <<< "$values")" - else - if ! values="$(dialog --stdout --no-cancel --separator ';:~:;' \ - --ok-label "Submit" --backtitle "$BT" --title " $title " \ - --insecure --mixedform "$_LuksOpenBody" 0 0 0 \ - "$_Name" 1 1 "$name" 1 $((${#_Name} + 2)) $COLUMNS 0 0 \ - "$_Password" 2 1 "" 2 $((${#_Password} + 2)) $COLUMNS 0 1 \ - "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) $COLUMNS 0 1)"; then - return 1 + + err=$? + (( err == 0 )) || break + + if [[ $onlypass ]]; then + pass="$(awk -F';:~:;' '{print $1}' <<< "$values")" + pass2="$(awk -F';:~:;' '{print $2}' <<< "$values")" + else + name="$(awk -F';:~:;' '{print $1}' <<< "$values")" + pass="$(awk -F';:~:;' '{print $2}' <<< "$values")" + pass2="$(awk -F';:~:;' '{print $3}' <<< "$values")" fi - name="$(awk -F';:~:;' '{print $1}' <<< "$values")" - pass="$(awk -F';:~:;' '{print $2}' <<< "$values")" - pass2="$(awk -F';:~:;' '{print $3}' <<< "$values")" - LUKS_NAME="$name" - fi - if [[ $pass == "" || "$pass" != "$pass2" ]]; then - msgbox "$_ErrTitle" "$_PassErr\n$_TryAgain" - luks_pass "$title" "$name" || return 1 - fi + if [[ ! $onlypass && $name == "" ]]; then + infobox "$_ErrTitle" "\nEncrypted device name cannot be empty.\n\n$_TryAgain" + elif [[ $pass == "" || "$pass" != "$pass2" ]]; then + [[ $onlypass ]] || LUKS_NAME="$name" + infobox "$_ErrTitle" "$_PassErr\n$_TryAgain" + else + [[ $onlypass ]] || LUKS_NAME="$name" + LUKS_PASS="$pass" + break + fi + done - LUKS_PASS="$pass" - return 0 + return $err } luks_setup() @@ -2251,7 +2262,7 @@ luks_setup() infobox "$_LuksEncrypt" "${_OnlyOne}: $LUKS_PART\n" 1 elif ! LUKS_PART="$(menubox "$_LuksEncrypt" "$_LuksEncryptBody" $PARTS)"; then return 1 - elif ! luks_pass "$_LuksEncrypt" "${LUKS_NAME:-cryptroot}"; then + elif ! luks_pass "$_LuksEncrypt"; then return 1 fi @@ -2300,6 +2311,7 @@ luks_show() luks_keyfile() { if [[ ! -e $MNT/crypto_keyfile.bin && $LUKS_PASS && $LUKS_UUID ]]; then + printf "Creating LUKS keyfile /crypto_keyfile.bin\n" local n n="$(lsblk -lno NAME,UUID,TYPE | awk "/$LUKS_UUID/"' && /part|crypt|lvm/ {print $1}')" local mkkey="dd bs=512 count=8 if=/dev/urandom of=/crypto_keyfile.bin" @@ -2385,7 +2397,7 @@ sigint() print4() { local str="$*" - if [[ $COLUMNS -gt 110 && ${#str} -gt $((COLUMNS - 10)) ]]; then + if [[ $COLUMNS -ge 110 && ${#str} -gt $((COLUMNS - 30)) ]]; then str="$(awk '{ i=2; p1=p2=p3=p4=""; p1=$1; q=int(NF / 4) for (;i<=q; i++) { p1=p1" "$i }