OSDN Git Service

Allow setting root and boot partitions before running
[pacbang-linux/installer-arch.git] / archlabs-installer
index 73eeab6..fc3a768 100755 (executable)
 # Some ideas and code reworked from other resources
 # AIF, Cnichi, Calamares, Arch Wiki.. Credit where credit is due
 
-VER="2.0.41"     # installer version
-DIST="ArchLabs"  # linux distributor
-MNT="/mnt"       # install mountpoint
-ANS="/tmp/ans"   # dialog answer file
-
-
-# --------------------------------------------- #
-# if you manually mount your partitions then you
-# need to set these values to avoid issues.
-# --------------------------------------------- #
-
-# root partition, eg/ /dev/sda2
-ROOT_PART=''
-
-# boot partition, required on UEFI eg. /dev/sda1
-BOOT_PART=''
-
-# device used for some bootloader install process, eg. /dev/sda
-BOOT_DEV=''
-
-# bootloader to use, can be:
-#    UEFI: grub, syslinux, efistub, systemd-boot, refind-efi
-#    BIOS: grub, syslinux
-BOOTLDR=''
-
-# directory to mount the boot partition (if any) for most bootloaders
-# this will need to be 'boot' however a popular one for grub is 'boot/efi'
-BOOTDIR='boot'
-
-# swap partition or file path
-SWAP_PART=''
-
-# swap size, only used when creating a swapfile
-SWAP_SIZE=''
-
-# --------------------------------------------- #
+VER=2.0.80
 
 # bulk default values {
 
-EXMNT=''          # holder for additional partitions while mounting
-EXMNTS=''         # when an extra partition is mounted append it's info
-
-FONT="ter-i16n"   # font used for the linux console
-HOOKS="shutdown"  # list of additional HOOKS to add in /etc/mkinitcpio.conf
-
-LOGINRC=''        # login shell rc file, eg. .zprofile, .bash_profile, .profile
-LOGIN_WM=''       # default login session to be placed in ~/.xinitrc
-INSTALL_WMS=''    # space separated list of chosen wm/de
-
-UCODE=''          # cpu microcode (if any), eg. amd-ucode, intel-ucode
-KERNEL=''         # can be linux, linux-lts, linux-zen, or linux-hardened
-MYSHELL=''        # full path for the shell, eg. /usr/bin/zsh
-
-WM_PKGS=''        # full list of packages added during wm/de choice
-PACKAGES=''       # list of all packages to install including WM_PKGS
-USER_PKGS=''      # packages selected by the user during install
-
-NEWUSER=''        # username for the new user
-USER_PASS=''      # new user's password
-ROOT_PASS=''      # root password
-
-LUKS=''           # empty when not using encryption
-LUKS_DEV=''       # boot parameter string for LUKS
-LUKS_PART=''      # partition used for encryption
-LUKS_PASS=''      # encryption password
-LUKS_UUID=''      # encrypted partition UUID
-LUKS_NAME=''      # name used for encryption
-
-LVM=''            # empty when not using lvm
-LVM_PARTS=''      # partitions used for volume group
-VGROUP_MB=0       # available space in volume group
-
-WARN=''           # issued mounting/partitioning warning
-SEP_BOOT=''       # separate boot partition for BIOS
-AUTOLOGIN=''      # enable autologin for xinit
-CONFIG_DONE=''    # basic configuration is finished
-BROADCOM_WL=''    # fixes for broadcom cards eg. BCM4352
-
-FORMATTED=''      # partitions we formatted and should allow skipping
-AUTO_ROOT_PART='' # root value from auto partition
-AUTO_BOOT_PART='' # boot value from auto partition
-
-# iso base, pacstrap when running the installer from a stock arch iso
-ISO_BASE="b43-firmware b43-fwcutter broadcom-wl clonezilla dhclient dhcpcd ethtool wpa_supplicant "
-ISO_BASE+="exfat-utils f2fs-tools gptfdisk vim hdparm ipw2100-fw ipw2200-fw nfs-utils nilfs-utils ntfs-3g "
-ISO_BASE+="pacman-contrib parted rsync sdparm smartmontools wget wireless_tools wpa_actiond xl2tpd dialog parted "
-ISO_BASE+="alsa-firmware alsa-lib alsa-plugins pulseaudio pulseaudio-alsa networkmanager w3m htop wireless-regdb "
-ISO_BASE+="lm_sensors lsb-release p7zip pamixer reflector unrar ranger terminus-font ttf-dejavu archlabs-keyring"
-
-# archlabs base packages
-AL_BASE_PKGS="archlabs-skel-base archlabs-fonts archlabs-themes archlabs-dARK archlabs-icons archlabs-wallpapers archlabs-scripts"
-
-# baseline (usually installed in the background)
-BASE_PKGS="base-devel xorg xorg-drivers xorg-xinit sudo git gvfs gtk3 gtk-engines gtk-engine-murrine pavucontrol tumbler "
-BASE_PKGS+="playerctl ffmpeg gstreamer libmad libmatroska gst-libav gst-plugins-base gst-plugins-good scrot"
-
-# extras for window managers
-WM_BASE_PKGS="arandr archlabs-networkmanager-dmenu xdg-user-dirs nitrogen polkit-gnome volumeicon xclip exo "
-WM_BASE_PKGS+="xdotool compton wmctrl 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
-VM="$(dmesg | grep -i "hypervisor")"  # is the system a vm
-SYS='Unknown'
-
-export DIALOGOPTS="--cr-wrap"
+: ${DIST=ArchLabs}                 # distro name if not set
+MNT=/mnt                           # install mountpoint
+ANS=/tmp/ans                       # dialog answer file
+BOOTDIR=boot                       # location to mount boot partition
+FONT=ter-i16n                      # font used for the linux console
+HOOKS=shutdown                     # list of additional mkinitcpio HOOKS
+SEL=0                              # currently selected menu item
+SYS=Unknown                        # bios type to be determined: UEFI/BIOS
+ERR=/tmp/errlog                    # error log used internally
+DBG=/tmp/debuglog                  # debug log when passed -d
+RUN=/run/archiso/bootmnt/arch/boot # path for live system /boot
+VM="$(dmesg | grep -i hypervisor)" # system running in a virtual machine
+export DIALOGOPTS="--cr-wrap"      # see `man dialog`
+
+BASE_PKGS="base base-devel xorg xorg-drivers sudo git gvfs gtk3 libmad libmatroska tumbler "
+BASE_PKGS+="playerctl pulseaudio pulseaudio-alsa pavucontrol pamixer scrot xdg-user-dirs "
+BASE_PKGS+="ffmpeg gstreamer gst-libav gst-plugins-base gst-plugins-good bash-completion "
+
+AL_BASE_PKGS="archlabs-keyring archlabs-icons archlabs-fonts archlabs-themes "
+AL_BASE_PKGS+="archlabs-baph archlabs-wallpapers archlabs-scripts archlabs-skel-base"
+
+WM_BASE_PKGS="arandr nitrogen polkit-gnome network-manager-applet "
+WM_BASE_PKGS+="volumeicon xclip exo laptop-detect xdotool compton wmctrl feh "
+WM_BASE_PKGS+="gnome-keyring dunst gsimplecal xfce4-power-manager xfce4-settings"
+
+SYS_MEM="$(awk '/MemTotal/ {print int($2 / 1024) "M"}' /proc/meminfo)"
+LOCALES="$(awk '/\.UTF-8/ {gsub(/# .*|#/, ""); if ($1) {print $1 " - "}}' /etc/locale.gen)"
+CMAPS="$(find /usr/share/kbd/keymaps -name '*.map.gz' | awk '{gsub(/\.map\.gz|.*\//, ""); print $1 " - "}' | sort)"
 
-# }
-
-# giant ugly variable container :P {
-
-# RAM in the system in MB
-SYS_MEM="$(awk '/MemTotal/ {
-print int($2 / 1024)"M"
-}' /proc/meminfo)"
-
-# locales from /etc/locale.gen
-LOCALES="$(awk '/\.UTF-8/ {
-       gsub(/# .*|#/, "")
-       if ($1) {
-               print $1 " - "
-       }
-}' /etc/locale.gen)"
-
-# linux console keyboard mappings
-CMAPS="$(find /usr/share/kbd/keymaps -name '*.map.gz' | awk '{
-       gsub(/\.map\.gz|.*\//, "")
-       print $1 " - "
-}' | sort)"
-
-# terminal size definitions
-# {
 [[ $LINES ]] || LINES=$(tput lines)
 [[ $COLUMNS ]] || COLUMNS=$(tput cols)
-SHL=$((LINES - 20)) # }
 
-# associative arrays
-# {
+# }
 
-# commands used to install each bootloader (most get modified during runtime) {
+# commands used to install each bootloader, however most get modified during runtime {
 declare -A BCMDS=(
 [refind-efi]='refind-install'
-[grub]='grub-install --recheck --force'
-[syslinux]='syslinux-install_update -i -a -m'
-[efistub]='efibootmgr -v -d /dev/sda -p 1 -c -l'
-[systemd-boot]='bootctl --path=/boot install'
+[grub]='grub-install --recheck --force' [syslinux]='syslinux-install_update -i -a -m'
+[efistub]='efibootmgr -v -d /dev/sda -p 1 -c -l' [systemd-boot]='bootctl --path=/boot install'
 ) # }
 
-# executable name for each wm/de {
+# executable name for each wm/de used in ~/.xinitrc {
 declare -A WM_SESSIONS=(
-[dwm]='dwm'
-[i3-gaps]='i3'
-[bspwm]='bspwm'
-[plasma]='startkde'
-[xfce4]='startxfce4'
-[gnome]='gnome-session'
-[fluxbox]='startfluxbox'
-[openbox]='openbox-session'
-[cinnamon]='cinnamon-session'
+[dwm]='dwm' [i3-gaps]='i3' [bspwm]='bspwm' [awesome]='awesome' [plasma]='startkde' [xfce4]='startxfce4'
+[gnome]='gnome-session' [fluxbox]='startfluxbox' [openbox]='openbox-session' [cinnamon]='cinnamon-session'
 ) # }
 
-# packages installed for each wm/de {
+# packages installed for each wm/de, most are depends of the skel packages {
 declare -A WM_EXT=(
-[dwm]=''
-[gnome]=''
-[plasma]='kdebase-meta'
-[bspwm]='sxhkd archlabs-skel-bspwm rofi archlabs-polybar'
-[fluxbox]='archlabs-skel-fluxbox archlabs-polybar jgmenu rofi lxmenu-data'
-[i3-gaps]='i3status perl-anyevent-i3 archlabs-skel-i3-gaps rofi archlabs-polybar'
-[openbox]='obconf archlabs-skel-openbox jgmenu archlabs-polybar tint2 conky rofi lxmenu-data'
-[xfce4]='xfce4-goodies xfce4-pulseaudio-plugin network-manager-applet volumeicon rofi archlabs-skel-xfce4'
+[dwm]='' [gnome]='' [cinnamon]='gnome-terminal' [plasma]='kdebase-meta'
+[awesome]='archlabs-skel-awesome' [bspwm]='archlabs-skel-bspwm' [fluxbox]='archlabs-skel-fluxbox'
+[i3-gaps]='archlabs-skel-i3-gaps' [openbox]='archlabs-skel-openbox' [xfce4]='archlabs-skel-xfce4 xfce4-goodies'
 ) # }
 
-# files that can be edited after install is complete {
+# files offered for editing after install is complete {
 declare -A EDIT_FILES=(
-[login]=''
-[fstab]='/etc/fstab'
-[sudoers]='/etc/sudoers'
-[crypttab]='/etc/crypttab'
-[pacman]='/etc/pacman.conf'
-[console]='/etc/vconsole.conf'
-[mkinitcpio]='/etc/mkinitcpio.conf'
-[hostname]='/etc/hostname /etc/hosts'
-[bootloader]="/boot/loader/entries/$DIST.conf"
-[locale]='/etc/locale.conf /etc/default/locale'
-[keyboard]='/etc/X11/xorg.conf.d/00-keyboard.conf /etc/default/keyboard'
+[login]='' # login is populated once we know the username and shell
+[fstab]='/etc/fstab' [sudoers]='/etc/sudoers' [crypttab]='/etc/crypttab' [pacman]='/etc/pacman.conf'
+[console]='/etc/vconsole.conf' [mkinitcpio]='/etc/mkinitcpio.conf' [hostname]='/etc/hostname /etc/hosts'
+[bootloader]="/boot/loader/entries/$DIST.conf"  # ** based on bootloader
+[locale]='/etc/locale.conf /etc/default/locale' [keyboard]='/etc/X11/xorg.conf.d/00-keyboard.conf /etc/default/keyboard'
 ) # }
 
-# mkfs command for formatting each offered filesystem {
-declare -A FS_CMDS=(
-[f2fs]='mkfs.f2fs'
-[jfs]='mkfs.jfs -q'
-[xfs]='mkfs.xfs -f'
-[ntfs]='mkfs.ntfs -q'
-[ext2]='mkfs.ext2 -q'
-[ext3]='mkfs.ext3 -q'
-[ext4]='mkfs.ext4 -q'
-[vfat]='mkfs.vfat -F32'
-[nilfs2]='mkfs.nilfs2 -q'
-[reiserfs]='mkfs.reiserfs -q'
+# mkfs command flags for filesystem formatting {
+declare -A FS_CMD_FLAGS=(
+[f2fs]='' [jfs]='-q' [xfs]='-f' [ntfs]='-q' [ext2]='-q' [ext3]='-q' [ext4]='-q' [vfat]='-F32' [nilfs2]='-q' [reiserfs]='-q'
 ) # }
 
-# mount options for each offered filesystem (if any {
+# mount options for each filesystem {
 declare -A FS_OPTS=(
-[vfat]=''
-[ntfs]=''
-[ext2]=''
-[ext3]=''
+[vfat]='' [ntfs]='' [ext2]='' [ext3]=''  # NA
 [jfs]='discard errors=continue errors=panic nointegrity'
 [reiserfs]='acl nolog notail replayonly user_xattr off'
 [ext4]='discard dealloc nofail noacl relatime noatime nobarrier nodelalloc'
@@ -224,38 +88,32 @@ declare -A FS_OPTS=(
 [f2fs]='discard fastboot flush_merge data_flush inline_xattr inline_data noinline_data inline_dentry no_heap noacl nobarrier norecovery noextent_cache disable_roll_forward disable_ext_identify'
 ) # }
 
-# PKG_EXT: if you add a package to $PACKAGES in any dialog {
-#          and it uses/requires some additional packages,
-#          you can add them here to keep it simple: [package]="extra"
-#          duplicates are removed with `uniq` before install
-declare -A PKG_EXT=(
-[vlc]='qt4'
-[mpd]='mpc'
-[mupdf]='mupdf-tools'
-[qt5ct]='qt5-styleplugins'
-[vlc]='qt5ct qt5-styleplugins'
-[zathura]='zathura-pdf-poppler'
-[noto-fonts]='noto-fonts-emoji'
-[cairo-dock]='cairo-dock-plug-ins'
-[qutebrowser]='qt5ct qt5-styleplugins'
-[qbittorrent]='qt5ct qt5-styleplugins'
-[transmission-qt]='qt5ct qt5-styleplugins'
-[kdenlive]='kdebase-meta dvdauthor frei0r-plugins breeze breeze-gtk qt5ct qt5-styleplugins'
+# packages installed for each login option {
+declare -A LOGIN_PKGS=(
+[xinit]='xorg-xinit' [ly]='archlabs-ly' [gdm]='gdm' [sddm]='sddm'
+[lightdm]='lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings accountsservice'
 ) # }
 
-# }
-
-# text variables
-# {
+# extras installed for user selected packages {
+# if a package requires additional packages that aren't already dependencies
+# they can be added here eg. [package]="extra"
+declare -A PKG_EXT=(
+[vlc]='qt4' [mpd]='mpc' [mupdf]='mupdf-tools'
+[rxvt-unicode]='urxvt-pearls' [zathura]='zathura-pdf-poppler' [noto-fonts]='noto-fonts-emoji' [cairo-dock]='cairo-dock-plug-ins' [qt5ct]='qt5-styleplugins'
+[vlc]='qt5ct qt5-styleplugins' [qutebrowser]='qt5ct qt5-styleplugins' [qbittorrent]='qt5ct qt5-styleplugins' [transmission-qt]='qt5ct qt5-styleplugins'
+[bluez]='bluez-libs bluez-utils bluez-tools bluez-plugins bluez-hid2hci' [kdenlive]='kdebase-meta dvdauthor frei0r-plugins breeze breeze-gtk qt5ct qt5-styleplugins'
+) # }
 
+# dialog text variables {
 # Basics (somewhat in order)
+_welcome="\nThis will help you get $DIST installed and setup on your system.\n\nIf you are unsure about a section the default option will be listed or\nthe first selected item will be the default.\n\n\nMenu Navigation:\n\n - Select items with the arrow keys or the option number.\n - Use [Space] to toggle check boxes and [Enter] to accept.\n - Switch between fields using [Tab] or the arrow keys.\n - Use [Page Up] and [Page Down] to jump whole pages\n - Press the highlighted key of an option to select it.\n"
 _keymap="\nPick which keymap to use for the system from the list below\n\nThis is used once a graphical environment is running (Xorg).\n\nSystem default: us"
 _vconsole="\nSelect the console keymap, the console is the tty shell you reach before starting a graphical environment (Xorg).\n\nIts keymap is seperate from the one used by the graphical environments, though many do use the same such as 'us' English.\n\nSystem default: us"
 _device="\nSelect a device to use from the list below.\n\nDevices (/dev) are the available drives on the system. /sda, /sdb, /sdc ..."
 _resize="\nSelect a new filesystem size in MB, a new partition will be created from the free space but will be left unformatted.\nThe lowest size is just enough to fit the currently in use space on the partition while the default is set to split the free space evenly.\n\nUse Tab or the arrow keys move the cursor between the buttons and the value, when the cursor is on the value, you can edit it by:\n\n - left/right cursor movement to select a digit to modify\n - +/-  characters to increment/decrement the digit by one\n - 0 through 9 to set the digit to the given value\n\nSome keys are also recognized in all cursor positions:\n\n - Home/End set the value to its maximum or minimum\n - Pageup/Pagedown increment the value so that the slider moves by one column."
 _mount="\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."
 _warn="\nIMPORTANT:\n\nChoose carefully when editing, formatting, and mounting partitions or your DATA MAY BE LOST.\n\nTo mount a partition without formatting it, select 'skip' when prompted to choose a filesystem during the mounting stage.\nThis can only be used for partitions that already contain a filesystem and cannot be the root (/) partition, it needs to be formatted before install.\n"
-_part="\nFull device auto partitioning is available for beginners otherwise cfdisk is recommended.\n\n  - All systems will require a root partition (8G or greater).\n  - UEFI (and BIOS using LUKS without LVM) require a separate boot partition (100-512M)."
+_part="\nFull device auto partitioning is available for beginners otherwise cfdisk is recommended.\n\n  - All systems will require a root partition (8G or greater).\n  - UEFI or BIOS using LUKS without LVM require a separate boot partition (100-512M)."
 _uefi="\nSelect the EFI boot partition (/boot), required for UEFI boot.\n\nIt's usually the first partition on the device, 100-512M, and will be formatted as vfat/fat32 if not already."
 _bios="\nDo you want to use a separate boot partition? (optional)\n\nIt's usually the first partition on the device, 100-512M, and will be formatted as ext3/4 if not already."
 _biosluks="\nSelect the boot partition (/boot), required for LUKS.\n\nIt's usually the first partition on the device, 100-512M, and will be formatted as ext3/4 if not already."
@@ -263,15 +121,16 @@ _format="is already formatted correctly.\n\nFor a clean install, previously exis
 _swapsize="\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 it is filled in to match the size of your system memory (RAM).\n\nMust be greater than 1, contain only whole numbers, and end with either M or G."
 _expart="\nYou can now choose any additional partitions you want mounted, you'll be asked for a mountpoint after.\n\nSelect 'done' to finish the mounting step and begin unpacking the base system in the background."
 _exmnt="\nWhere do you want the partition mounted?\n\nEnsure the name begins with a slash (/).\nExamples include: /usr, /home, /var, etc."
-_user="\nEnter a name and password for the new user account.\n\nThe name must not use capital letters, contain any periods (.), end with a hyphen (-), or include any colons (:)\n\nNOTE: Use the [Up] and [Down] arrows to switch between input fields, [Tab] to toggle between input fields and the buttons, and [Enter] to accept."
+_user="\nEnter a name and password for the new user account.\n\nThe name must not use capital letters, contain any periods (.), end with a hyphen (-), or include any colons (:)\n\nNOTE: Use [Up], [Down], or [Tab] to switch between fields, and [Enter] to accept."
 _hostname="\nEnter a hostname for the new system.\n\nA hostname is used to identify systems on the network.\n\nIt's restricted to alphanumeric characters (a-z, A-Z, 0-9).\nIt can contain hyphens (-) BUT NOT at the beggining or end."
 _locale="\nLocale determines the system language and currency formats.\n\nThe format for locale names is languagecode_COUNTRYCODE\n\neg. en_US is: english United States\n    en_GB is: english Great Britain"
 _timez="\nThe time zone is used to set the system clock.\n\nSelect your country or continent from the list below"
 _timesubz="\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."
 _sessions="\nUse [Space] to toggle available sessions, use [Enter] to accept the selection and continue.\n\nA basic package set will be installed for compatibility and functionality."
 _login="\nSelect which of your session choices to use for the initial login.\n\nYou can be change this later by editing your ~/.xinitrc"
+_autologin="\nDo you want autologin enabled for USER?\n\nIf so the following two files will be created (disable autologin by removing them):\n\n - /home/USER/RC (run startx when logging in on tty1)\n - /etc/systemd/system/getty@tty1.service.d/autologin.conf (login USER without password)\n"
 _packages="\nUse [Space] to move a package into the selected area and press [Enter] to accept the selection.\n\nPackages may be installed by your DE/WM (if any), or for the packages you select."
-_edit="\nBefore exiting you can select configuration files to review/change.\n\nIf you need to make other changes with the drives still mounted, use Ctrl-z to pause the installer, when finished type 'fg' and [Enter] or Ctrl-z again to resume the installer, if you want to avoid the automatic reboot using Ctrl-c will cleanly exit."
+_edit="\nBefore exiting you can select configuration files to review/change.\n\nIf you need to make other changes with the drives still mounted, use Ctrl-z to pause the installer, when finished type 'fg' and [Enter] to resume the installer, if you want to avoid the automatic reboot using Ctrl-c will cleanly exit."
 
 # LUKS
 _luksnew="Basic LUKS Encryption"
@@ -302,12 +161,13 @@ _lvmerrlvsize="\nInvalid value Entered.\n\nMust be a numeric value with 'M' (meg
 
 # }
 
-# }
-
 ###############################################################################
 # selection menus
+# main is the entry point which calls functions including outside of its block
+# once those functions finished they always are returned here with the
+# exception of install_main(), it exits upon completion
 
-select_main()
+main()
 {
        (( SEL < 12 )) && (( SEL++ ))
        tput civis
@@ -332,7 +192,7 @@ select_main()
                2) part_menu || (( SEL-- )) ;;
                3) luks_menu || (( SEL-- )) ;;
                4) lvm_menu || (( SEL-- )) ;;
-               5) select_menu || (( SEL-- )) ;;
+               5) mount_menu || (( SEL-- )) ;;
                6) prechecks 0 && { select_boot || (( SEL-- )); } ;;
                7) prechecks 1 && { select_mkuser || (( SEL-- )); } ;;
                8) prechecks 2 && { select_config || (( SEL-- )); } ;;
@@ -363,33 +223,23 @@ select_boot()
 
 select_show()
 {
-       local mnt="none"
-       local cmd="${BCMDS[$BOOTLDR]}"
        local pkgs="${USER_PKGS//  / } ${PACKAGES//  / }"
-       [[ $BOOT_PART ]] && mnt="/$BOOTDIR"
+       [[ $BOOT_PART ]] && local mnt="/$BOOTDIR"
        [[ $INSTALL_WMS == *dwm* ]] && pkgs="dwm st dmenu $pkgs"
+       pkgs="${pkgs//  / }" pkgs="${pkgs# }"
        msg "Show Configuration" "
-
 ---------- PARTITION CONFIGURATION ------------
 
   Root:  ${ROOT_PART:-none}
   Boot:  ${BOOT_PART:-${BOOT_DEV:-none}}
-
+  Mount: ${mnt:-none}
   Swap:  ${SWAP_PART:-none}
   Size:  ${SWAP_SIZE:-none}
-
-  LVM:   ${LVM:-none}
-  LUKS:  ${LUKS:-none}
-
   Extra: ${EXMNTS:-${EXMNT:-none}}
   Hooks: ${HOOKS:-none}
 
-
----------- BOOTLOADER CONFIGURATION -----------
-
-  Bootloader: ${BOOTLDR:-none}
-  Mountpoint: ${mnt:-none}
-  Command:    ${cmd:-none}
+  LVM:   ${LVM:-none}
+  LUKS:  ${LUKS:-none}
 
 
 ------------ SYSTEM CONFIGURATION -------------
@@ -400,35 +250,49 @@ select_show()
   Timezone: ${ZONE:-none}/${SUBZ:-none}
 
 
------------- USER CONFIGURATION --------------
+------------ USER CONFIGURATION ---------------
 
-  User:         ${NEWUSER:-none}
-  Shell:        ${MYSHELL:-none}
-  Session:      ${LOGIN_WM:-none}
-  Autologin:    ${AUTOLOGIN:-none}
-  Login Method: ${LOGIN_TYPE:-none}
+  Username:      ${NEWUSER:-none}
+  Login Shell:   ${MYSHELL:-none}
+  Login Session: ${LOGIN_WM:-none}
+  Autologin:     ${AUTOLOGIN:-none}
+  Login Type:    ${LOGIN_TYPE:-none}
 
 
------------- PACKAGES AND MIRRORS -------------
+----------- PACKAGE CONFIGURATION -------------
 
-  Kernel:   ${KERNEL:-none}
-  Sessions: ${INSTALL_WMS:-none}
-  Packages: $(print4 "${pkgs:-none}")
+  Kernel:     ${KERNEL:-none}
+  Bootloader: ${BOOTLDR:-none}
+  Packages:   ${pkgs:-none}
 "
 }
 
 select_login()
 {
-       if (( WM_NUM == 1 )); then
-               LOGIN_WM="${WM_SESSIONS[$INSTALL_WMS]}"
-       else
-               dlg LOGIN_WM menu "Login Session" "$_login" $LOGIN_CHOICES || return 1
-               LOGIN_WM="${WM_SESSIONS[$LOGIN_WM]}"
-       fi
-
-       local txt="\nDo you want autologin enabled for $NEWUSER?\n\nThe following two files will be created (disable autologin by remove them):\n\n  - /home/$NEWUSER/$LOGINRC (this runs startx when logging in on tty1)\n  - /etc/systemd/system/getty@tty1.service.d/autologin.conf (this logs in $NEWUSER without a password)\n"
-       yesno "Autologin" "$txt" && AUTOLOGIN=true || AUTOLOGIN=''
-       EDIT_FILES[login]="/home/$NEWUSER/.xinitrc /home/$NEWUSER/.xprofile"
+       [[ $INSTALL_WMS ]] || return 0
+
+       AUTOLOGIN='' # no autologin unless using xinit
+
+       dlg LOGIN_TYPE menu "Login Management" "\nSelect what kind of login management to use." \
+               "xinit"   "Console login without a display manager" \
+               "ly"      "TUI display manager with a ncurses-like interface" \
+               "lightdm" "Lightweight display manager with a gtk greeter" \
+               "gdm"     "Gnome display manager" \
+               "sddm"    "Simple desktop display manager" || return 1
+
+       case $LOGIN_TYPE in
+               ly) EDIT_FILES[login]="/etc/ly/config.ini" ;;
+               gdm|sddm) EDIT_FILES[login]="" ;;
+               lightdm) EDIT_FILES[login]="/etc/lightdm/lightdm.conf /etc/lightdm/lightdm-gtk-greeter.conf" ;;
+               xinit) EDIT_FILES[login]="/home/$NEWUSER/.xinitrc /home/$NEWUSER/.xprofile"
+                       if (( $(wc -w <<< "$INSTALL_WMS") > 1 )); then
+                               dlg LOGIN_WM menu "Login Management" "$_login" $LOGIN_CHOICES || return 1
+                               LOGIN_WM="${WM_SESSIONS[$LOGIN_WM]}"
+                       fi
+                       [[ -z $LOGIN_WM ]] && LOGIN_WM="${WM_SESSIONS[${INSTALL_WMS%% *}]}"
+                       yesno "Autologin" "$(sed "s|USER|$NEWUSER|g; s|RC|$LOGINRC|g" <<< "$_autologin")" && AUTOLOGIN=true || AUTOLOGIN=''
+                       ;;
+       esac
 }
 
 select_config()
@@ -438,12 +302,10 @@ select_config()
 
        until [[ $CONFIG_DONE ]]; do
                case $i in
-                       0)
-                               dlg MYSHELL menu "Shell" "\nChoose which shell to use." \
-                                       /usr/bin/zsh  'A very advanced and programmable command interpreter (shell) for UNIX' \
-                                       /bin/bash     'The GNU Bourne Again shell, standard in many GNU/Linux distributions' \
-                                       /usr/bin/mksh 'The MirBSD Korn Shell - an enhanced version of the public domain ksh' || return 1
-
+                       0) dlg MYSHELL menu "Shell" "\nChoose which shell to use." \
+                                       zsh  'A very advanced and programmable command interpreter (shell) for UNIX' \
+                                       bash 'The GNU Bourne Again shell, standard in many GNU/Linux distributions' \
+                                       mksh 'The MirBSD Korn Shell - an enhanced version of the public domain ksh' || return 1
                                ;;
                        1) dlg MYHOST input "Hostname" "$_hostname" "${DIST,,}" limit || { i=0; continue; } ;;
                        2) dlg MYLOCALE menu "Locale" "$_locale" $LOCALES || { i=1; continue; } ;;
@@ -451,16 +313,13 @@ select_config()
                                until [[ $ZONE && $SUBZ ]]; do
                                        dlg ZONE menu "Timezone" "$_timez" America - Australia - Asia - Atlantic - Africa - Europe - Indian - Pacific - Arctic - Antarctica - || break
                                        dlg SUBZ menu "Timezone" "$_timesubz" $(awk '/'"$ZONE"'\// {gsub(/'"$ZONE"'\//, ""); print $3 " - "}' /usr/share/zoneinfo/zone.tab | sort) || continue
-                                       yesno "Timezone" "\nConfirm time zone: $ZONE/$SUBZ\n" || unset ZONE
                                done
                                [[ $ZONE && $SUBZ ]] || { i=2; continue; } ;;
-                       4)
-                               dlg KERNEL menu "Kernel" "\nChoose which kernel to use." \
+                       4) dlg KERNEL menu "Kernel" "\nChoose which kernel to use." \
                                        linux          'Vanilla linux kernel and modules, with a few patches applied' \
                                        linux-lts      'Long-term support (LTS) linux kernel and modules' \
                                        linux-zen      'A effort of kernel hackers to provide the best kernel for everyday systems' \
                                        linux-hardened 'A security-focused linux kernel with hardening patches to mitigate exploits' || { i=3; continue; }
-
                                CONFIG_DONE=true
                                ;;
                esac
@@ -468,9 +327,9 @@ select_config()
        done
 
        case $MYSHELL in
-               '/bin/bash') LOGINRC='.bash_profile' ;;
-               '/usr/bin/zsh') LOGINRC='.zprofile' ;;
-               '/usr/bin/mksh') LOGINRC='.profile' ;;
+               bash) LOGINRC='.bash_profile' ;;
+               zsh) LOGINRC='.zprofile' ;;
+               mksh) LOGINRC='.profile' ;;
        esac
 
        return 0
@@ -479,46 +338,37 @@ select_config()
 select_mkuser()
 {
        NEWUSER=''
-       local v='' u='' p='' p2='' rp='' rp2=''
+       typeset -a ans
 
        until [[ $NEWUSER ]]; do
-               i=0
                tput cnorm
                dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" --separator $'\n' --title " User " --mixedform "$_user" 0 0 0 \
-                       "Username:"  1 1 "$u" 1 11 "$COLUMNS" 0 0 \
-                       "Password:"  2 1 ''   2 11 "$COLUMNS" 0 1 \
-                       "Password2:" 3 1 ''   3 12 "$COLUMNS" 0 1 \
+                       "Username:"  1 1 "${ans[0]}" 1 11 "$COLUMNS" 0 0 \
+                       "Password:"  2 1 ''          2 11 "$COLUMNS" 0 1 \
+                       "Password2:" 3 1 ''          3 12 "$COLUMNS" 0 1 \
                        "--- Root password, if left empty the user password will be used ---" 6 1 '' 6 68 "$COLUMNS" 0 2 \
-                       "Password:"  8 1 ''   8 11 "$COLUMNS" 0 1 \
-                       "Password2:" 9 1 ''   9 12 "$COLUMNS" 0 1 2>"$ANS" || return 1
-
-               while read -r line; do
-                       case $i in
-                               0) u="$line" ;;
-                               1) p="$line" ;;
-                               2) p2="$line" ;;
-                               3) rp="$line" ;;
-                               4) rp2="$line" ;;
-                       esac
-                       (( i++ ))
-               done < "$ANS"
+                       "Password:"  8 1 ''          8 11 "$COLUMNS" 0 1 \
+                       "Password2:" 9 1 ''          9 12 "$COLUMNS" 0 1 2>"$ANS" || return 1
+
+               mapfile -t ans <"$ANS"
 
                # root passwords empty, so use the user passwords
-               [[ -z $rp && -z $rp2 ]] && { rp="$p"; rp2="$p2"; }
+               if [[ -z "${ans[4]}" && -z "${ans[5]}" ]]; then
+                       ans[4]="${ans[1]}"
+                       ans[5]="${ans[2]}"
+               fi
 
                # make sure a username was entered and that the passwords match
-               if [[ ${#u} -eq 0 || $u =~ \ |\' || $u =~ [^a-z0-9] ]]; then
-                       msg "Invalid Username" "\nIncorrect user name.\n\nPlease try again.\n"; u=''
-               elif [[ -z $p ]]; then
-                       msg "Empty Password" "\nThe user password cannot be left empty.\n\nPlease try again.\n"
-               elif [[ "$p" != "$p2" ]]; then
+               if [[ -z ${ans[0]} || ${ans[0]} =~ \ |\' || ${ans[0]} =~ [^a-z0-9] ]]; then
+                       msg "Invalid Username" "\nInvalid user name.\n\nPlease try again.\n"; u=''
+               elif [[ -z "${ans[1]}" || "${ans[1]}" != "${ans[2]}" ]]; then
                        msg "Password Mismatch" "\nThe user passwords do not match.\n\nPlease try again.\n"
-               elif [[ "$rp" != "$rp2" ]]; then
+               elif [[ "${ans[4]}" != "${ans[5]}" ]]; then
                        msg "Password Mismatch" "\nThe root passwords do not match.\n\nPlease try again.\n"
                else
-                       NEWUSER="$u"
-                       USER_PASS="$p"
-                       ROOT_PASS="$rp"
+                       NEWUSER="${ans[0]}"
+                       USER_PASS="${ans[1]}"
+                       ROOT_PASS="${ans[4]}"
                fi
        done
        return 0
@@ -554,10 +404,10 @@ select_keymap()
                dlg CMAP menu "Console Keymap" "$_vconsole" $CMAPS || return 1
        fi
 
-       if [[ $DISPLAY && $TERM != 'linux' ]]; then
-               setxkbmap "$KEYMAP" >/dev/null 2>&1
-       else
+       if [[ $TERM == 'linux' ]]; then
                loadkeys "$CMAP" >/dev/null 2>&1
+       else
+               setxkbmap "$KEYMAP" >/dev/null 2>&1
        fi
 
        return 0
@@ -566,31 +416,24 @@ select_keymap()
 select_sessions()
 {
        LOGIN_CHOICES=''
-
        dlg INSTALL_WMS check "Sessions" "$_sessions\n" \
-               i3-gaps "A fork of i3wm with more features including gaps" "$(ofn i3-gaps "${INSTALL_WMS[*]}")" \
                openbox "A lightweight, powerful, and highly configurable stacking wm" "$(ofn openbox "${INSTALL_WMS[*]}")" \
+               i3-gaps "A fork of i3wm with more features including gaps" "$(ofn i3-gaps "${INSTALL_WMS[*]}")" \
+               dwm "A dynamic WM for X that manages windows in tiled, floating, or monocle layouts" "$(ofn dwm "${INSTALL_WMS[*]}")" \
                bspwm "A tiling wm that represents windows as the leaves of a binary tree" "$(ofn bspwm "${INSTALL_WMS[*]}")" \
-               dwm "A fork of dwm, with more layouts and features" "$(ofn dwm "${INSTALL_WMS[*]}")" \
+               xfce4 "A lightweight and modular desktop environment based on gtk+2/3" "$(ofn xfce4 "${INSTALL_WMS[*]}")" \
+               awesome "A customized Awesome WM session created by @elanapan" "$(ofn awesome "${INSTALL_WMS[*]}")" \
                fluxbox "A lightweight and highly-configurable window manager" "$(ofn fluxbox "${INSTALL_WMS[*]}")" \
-               gnome "A desktop environment that aims to be simple and easy to use" "$(ofn gnome "${INSTALL_WMS[*]}")" \
-               cinnamon "A desktop environment combining traditional desktop with modern effects" "$(ofn cinnamon "${INSTALL_WMS[*]}")" \
                plasma "A kde software project currently comprising a full desktop environment" "$(ofn plasma "${INSTALL_WMS[*]}")" \
-               xfce4 "A lightweight and modular desktop environment based on gtk+2/3" "$(ofn xfce4 "${INSTALL_WMS[*]}")" || return 1
-
-       WM_NUM=0
-       while IFS=' ' read -r i; do
-               (( WM_NUM++ ))
-       done <<< "$INSTALL_WMS"
+               gnome "A desktop environment that aims to be simple and easy to use" "$(ofn gnome "${INSTALL_WMS[*]}")" \
+               cinnamon "A desktop environment combining traditional desktop with modern effects" "$(ofn cinnamon "${INSTALL_WMS[*]}")"
 
+       [[ $INSTALL_WMS ]] || return 0
 
        WM_PKGS="${INSTALL_WMS/dwm/}" # remove dwm from package list
        WM_PKGS="${WM_PKGS//  / }"    # remove double spaces
        WM_PKGS="${WM_PKGS# }"        # remove leading space
 
-       # add archlabs base when choosing any session
-       [[ $WM_PKGS ]] && WM_PKGS+=" $AL_BASE_PKGS"
-
        for i in $INSTALL_WMS; do
                LOGIN_CHOICES+="$i - "
                [[ ${WM_EXT[$i]} && $WM_PKGS != *"${WM_EXT[$i]}"* ]] && WM_PKGS+=" ${WM_EXT[$i]}"
@@ -613,6 +456,8 @@ select_packages()
                atom "An open-source text editor developed by GitHub" "$(ofn atom "${USER_PKGS[*]}")" \
                audacious "A free and advanced audio player based on GTK+" "$(ofn audacious "${USER_PKGS[*]}")" \
                audacity "A program that lets you manipulate digital audio waveforms" "$(ofn audacity "${USER_PKGS[*]}")" \
+               blueman "GUI bluetooth device manager" "$(ofn blueman "${USER_PKGS[*]}")" \
+               bluez "Simple CLI based bluetooth support" "$(ofn bluez "${USER_PKGS[*]}")" \
                cairo-dock "Light eye-candy fully themable animated dock" "$(ofn cairo-dock "${USER_PKGS[*]}")" \
                calligra "A set of applications for productivity" "$(ofn calligra "${USER_PKGS[*]}")" \
                chromium "An open-source web browser based on the Blink rendering engine" "$(ofn chromium "${USER_PKGS[*]}")" \
@@ -620,7 +465,6 @@ select_packages()
                cmus "A small, fast and powerful console music player" "$(ofn cmus "${USER_PKGS[*]}")" \
                deadbeef "A GTK+ audio player for GNU/Linux" "$(ofn deadbeef "${USER_PKGS[*]}")" \
                deluge "A BitTorrent client written in python" "$(ofn deluge "${USER_PKGS[*]}")" \
-               docky "Full fledged dock for opening applications and managing windows" "$(ofn docky "${USER_PKGS[*]}")" \
                emacs "An extensible, customizable, self-documenting real-time display editor" "$(ofn emacs "${USER_PKGS[*]}")" \
                epiphany "A GNOME web browser based on the WebKit rendering engine" "$(ofn epiphany "${USER_PKGS[*]}")" \
                evince "A document viewer" "$(ofn evince "${USER_PKGS[*]}")" \
@@ -631,6 +475,7 @@ select_packages()
                geany "A fast and lightweight IDE" "$(ofn geany "${USER_PKGS[*]}")" \
                geary "A lightweight email client for the GNOME desktop" "$(ofn geary "${USER_PKGS[*]}")" \
                gimp "GNU Image Manipulation Program" "$(ofn gimp "${USER_PKGS[*]}")" \
+               gnome-calculator "GNOME Scientific calculator" "$(ofn gnome-calculator "${USER_PKGS[*]}")" \
                gnome-disk-utility "Disk Management Utility" "$(ofn gnome-disk-utility "${USER_PKGS[*]}")" \
                gnome-system-monitor "View current processes and monitor system state" "$(ofn gnome-system-monitor "${USER_PKGS[*]}")" \
                gparted "A GUI frontend for creating and manipulating partition tables" "$(ofn gparted "${USER_PKGS[*]}")" \
@@ -652,7 +497,6 @@ select_packages()
                nautilus "The default file manager for Gnome" "$(ofn nautilus "${USER_PKGS[*]}")" \
                ncmpcpp "A mpd client and almost exact clone of ncmpc with some new features" "$(ofn ncmpcpp "${USER_PKGS[*]}")" \
                neovim "A fork of Vim aiming to improve user experience, plugins, and GUIs." "$(ofn neovim "${USER_PKGS[*]}")" \
-               nicotine+ "A graphical client for Soulseek" "$(ofn nicotine+ "${USER_PKGS[*]}")" \
                noto-fonts "Google Noto fonts" "$(ofn noto-fonts "${USER_PKGS[*]}")" \
                noto-fonts-cjk "Google Noto CJK fonts (Chinese, Japanese, Korean)" "$(ofn noto-fonts-cjk "${USER_PKGS[*]}")" \
                obs-studio "Free opensource streaming/recording software" "$(ofn obs-studio "${USER_PKGS[*]}")" \
@@ -668,6 +512,7 @@ select_packages()
                rhythmbox "A Music playback and management application" "$(ofn rhythmbox "${USER_PKGS[*]}")" \
                rxvt-unicode "A unicode enabled rxvt-clone terminal emulator" "$(ofn rxvt-unicode "${USER_PKGS[*]}")" \
                sakura "A terminal emulator based on GTK and VTE" "$(ofn sakura "${USER_PKGS[*]}")" \
+               simple-scan "Simple scanning utility" "$(ofn simple-scan "${USER_PKGS[*]}")" \
                simplescreenrecorder "A feature-rich screen recorder" "$(ofn simplescreenrecorder "${USER_PKGS[*]}")" \
                steam "A popular game distribution platform by Valve" "$(ofn steam "${USER_PKGS[*]}")" \
                surf "A simple web browser based on WebKit2/GTK+" "$(ofn surf "${USER_PKGS[*]}")" \
@@ -678,20 +523,23 @@ select_packages()
                tilda "A GTK based drop down terminal for Linux and Unix" "$(ofn tilda "${USER_PKGS[*]}")" \
                tilix "A tiling terminal emulator for Linux using GTK+ 3" "$(ofn tilix "${USER_PKGS[*]}")" \
                transmission-cli "Free BitTorrent client CLI" "$(ofn transmission-cli "${USER_PKGS[*]}")" \
-               transmission-gtk "Free BitTorrent client GTK+ GUI" "$(ofn transmission-gtk "${USER_PKGS[*]}")" \
-               transmission-qt "Free BitTorrent client Qt GUI" "$(ofn transmission-qt "${USER_PKGS[*]}")" \
+               transmission-gtk "GTK+ Front end for transmission" "$(ofn transmission-gtk "${USER_PKGS[*]}")" \
+               transmission-qt "Qt Front end for transmission" "$(ofn transmission-qt "${USER_PKGS[*]}")" \
                ttf-anonymous-pro "A family fixed-width fonts designed with code in mind" "$(ofn ttf-anonymous-pro "${USER_PKGS[*]}")" \
                ttf-fira-code "Monospaced font with programming ligatures" "$(ofn ttf-fira-code "${USER_PKGS[*]}")" \
                ttf-font-awesome "Iconic font designed for Bootstrap" "$(ofn ttf-font-awesome "${USER_PKGS[*]}")" \
                ttf-hack "A hand groomed typeface based on Bitstream Vera Mono" "$(ofn ttf-hack "${USER_PKGS[*]}")" \
                vlc "A free and open source cross-platform multimedia player" "$(ofn vlc "${USER_PKGS[*]}")" \
                weechat "Fast, light and extensible IRC client" "$(ofn weechat "${USER_PKGS[*]}")" \
+               xapps "Common library for X-Apps project" "$(ofn xapps "${USER_PKGS[*]}")" \
                xarchiver "A GTK+ frontend to various command line archivers" "$(ofn xarchiver "${USER_PKGS[*]}")" \
-               xfce-terminal "A terminal emulator based in the Xfce Desktop Environment" "$(ofn xfce-terminal "${USER_PKGS[*]}")" \
+               xed "A small and lightweight text editor. X-Apps Project." "$(ofn xed "${USER_PKGS[*]}")" \
+               xfce4-terminal "A terminal emulator based in the Xfce Desktop Environment" "$(ofn xfce4-terminal "${USER_PKGS[*]}")" \
+               xreader "Document viewer for files like PDF and Postscript. X-Apps Project." "$(ofn xed "${USER_PKGS[*]}")" \
                xterm "The standard terminal emulator for the X window system" "$(ofn xterm "${USER_PKGS[*]}")" \
                zathura "Minimalistic document viewer" "$(ofn zathura "${USER_PKGS[*]}")"
 
-       if [[ $USER_PKGS ]]; then
+       if [[ $USER_PKGS ]]; then    # add any needed PKG_EXT to the list
                for i in $USER_PKGS; do
                        [[ ${PKG_EXT[$i]} && $USER_PKGS != *"${PKG_EXT[$i]}"* ]] && USER_PKGS+=" ${PKG_EXT[$i]}"
                done
@@ -701,39 +549,30 @@ select_packages()
 }
 
 ###############################################################################
-# partition menus
+# partitioning menus
+# non-essential partitioning helpers called by the user when using the optional
+# partition menu and selecting a device to edit
 
 part_menu()
 {
-       check_background_install || return 0
+       no_bg_install || return 0
        local device choice devhash
        devhash="$(lsblk -f | base64)"
        umount_dir $MNT
        part_device || return 1
        device="$DEVICE"
 
-       while true; do
+       while :; do
                choice=""
-               if [[ $DISPLAY && $TERM != 'linux' ]] && hash gparted >/dev/null 2>&1; then
-                       dlg choice menu "Edit Partitions" "$_part" \
-                               "auto"    "Whole device automatic partitioning" \
-                               "shrink"  "Shrink an existing ext2/3/4 or ntfs partition to make room for a new partition" \
-                               "gparted" "GUI front end to parted" \
-                               "cfdisk"  "Curses based variant of fdisk" \
-                               "parted"  "GNU partition editor" \
-                               "fdisk"   "Dialog-driven creation and manipulation of partitions" \
-                               "done"    "Return to the main menu" || return 0
-               else
-                       dlg choice menu "Edit Partitions" "$_part" \
-                               "auto"   "Whole device automatic partitioning" \
-                               "shrink" "Shrink an existing ext2/3/4 or ntfs partition to make room for a new partition" \
-                               "cfdisk" "Curses based variant of fdisk" \
-                               "parted" "GNU partition editor" \
-                               "fdisk"  "Dialog-driven creation and manipulation of partitions" \
-                               "done"   "Return to the main menu" || return 0
-               fi
-
-               if [[ $choice == 'done' ]]; then
+               dlg choice menu "Edit Partitions" "$_part\n\n$(lsblk -no NAME,MODEL,SIZE,TYPE,FSTYPE $device)" \
+                       "auto"   "Whole device automatic partitioning" \
+                       "shrink" "Shrink an existing ext or ntfs partition" \
+                       "cfdisk" "Curses based variant of fdisk" \
+                       "parted" "GNU partition editor" \
+                       "fdisk"  "Dialog-driven creation and manipulation of partitions" \
+                       "done"   "Return to the main menu"
+
+               if [[ -z $choice || $choice == 'done' ]]; then
                        return 0
                elif [[ $choice == 'shrink' ]]; then
                        part_shrink "$device"
@@ -764,8 +603,9 @@ part_menu()
                        $choice "$device"
                fi
                if [[ $devhash != "$(lsblk -f | base64)" ]]; then
-                       msg "Probing Partitions" "\nInforming the kernel of partition changes using partprobe.\n" 0
+                       msg "Probing Partitions" "\nInforming kernel of partition changes using partprobe\n" 0
                        partprobe >/dev/null 2>&1
+                       [[ $choice == 'auto' ]] && return
                fi
        done
 }
@@ -781,21 +621,6 @@ part_show()
        msg "Device Tree" "\n\n$txt\n\n"
 }
 
-part_swap()
-{
-       if [[ $1 == "$MNT/swapfile" && $SWAP_SIZE ]]; then
-               fallocate -l $SWAP_SIZE "$1" 2>$ERR
-               errshow "fallocate -l $SWAP_SIZE $1"
-               chmod 600 "$1" 2>$ERR
-               errshow "chmod 600 $1"
-       fi
-       mkswap "$1" >/dev/null 2>$ERR
-       errshow "mkswap $1"
-       swapon "$1" >/dev/null 2>$ERR
-       errshow "swapon $1"
-       return 0
-}
-
 part_auto()
 {
        local device="$1" table="$2" boot_fs="$3" size="$4" dev_info=""
@@ -833,10 +658,77 @@ part_auto()
        AUTO_ROOT_PART="$(lsblk -lno NAME,TYPE "$device" | awk 'NR==3 {print "/dev/" $1}')"
        mkfs.ext4 -q "$AUTO_ROOT_PART" >/dev/null 2>&1
        sleep 0.5
-       FORMATTED+="$AUTO_BOOT_PART $AUTO_ROOT_PART "
        msg "Auto Partition" "\nProcess complete.\n\n$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE "$device")\n"
 }
 
+part_shrink()
+{
+       part=""
+       typeset -i size num
+       local device="$1" fs=""
+
+       part_find "${device##*/}[^ ]" || return 1
+       (( COUNT == 1 )) && part="$(awk '{print $1}' <<< "${PARTS[@]}" )"
+
+       if (( COUNT == 1 )) || dlg part menu "Resize" "\nWhich partition on $device do you want to resize?" $PARTS; then
+               fs=$(lsblk -lno FSTYPE "$part")
+               case "$fs" in
+                       ext*|ntfs)
+                               msg "Resize" "\nGathering device size info.\n" 0
+                               num="${part: -1}"
+                               end=$(parted -s "$device" unit KiB print | awk '/^\s*'"$num"'/ {print $3}')                    # part size in KiB
+                               devsize=$(parted -s "$device" unit KiB print | awk '/Disk '"${device//\//\\/}"':/ {print $3}') # whole device size in KiB
+                               mount "$part" $MNT >/dev/null 2>&1; sleep 0.5
+                               min=$(df --output=used --block-size=MiB "$part" | awk 'NR == 2 {print int($1) + 256}')
+                               max=$(df --output=avail --block-size=MiB "$part" | awk 'NR == 2 {print int($1)}')
+                               umount_dir $MNT
+                               tput cnorm
+                               if dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Resize: $part " --rangebox "$_resize" 17 "$COLUMNS" "$min" "$max" $((max / 2)) 2>$ANS; then
+                                       size=$(< "$ANS")
+                                       size=$((size * 1024))
+                               else
+                                       return 1
+                               fi
+                               clear
+                               case "$fs" in
+                                       ntfs)
+                                               if ntfsresize -fc "$part"; then
+                                                       ntfsresize -ff --size $(( (size * 1024) / 1000 ))k "$part" 2>$ERR # k=10^3 bytes
+                                                       errshow "ntfsresize -f -s $(( (size * 1024) / 1000 ))k $part" || return 1
+                                               else
+                                                       msg "Resize" "\nThe ntfs partition $part cannot be resized because it is scheduled for a consistency check.\n\nTo do a consistency check in windows open command prompt as admin and run:\n\n\tchkdsk /f /r /x\n"
+                                                       return 1
+                                               fi
+                                               ;;
+                                       *)
+                                               e2fsck -f "$part"; sleep 0.5
+                                               resize2fs -f "$part" ${size}K 2>$ERR # K=2^10 bytes
+                                               errshow "resize2fs -f $part ${size}K" || return 1
+                                               ;;
+                               esac
+                               sleep 0.5
+                               parted "$device" resizepart "$num" ${size}KiB || return 1
+                               (( size++ ))
+                               sleep 0.5
+                               if [[ $devsize == "$end" ]]; then
+                                       parted -s "$device" mkpart primary ext4 ${size}KiB 100% 2>$ERR
+                                       errshow "parted -s $device mkpart primary ext4 ${size}KiB 100%" || return 1
+                               else
+                                       parted -s "$device" mkpart primary ext4 ${size}KiB ${end}KiB 2>$ERR
+                                       errshow "parted -s $device mkpart primary ext4 ${size}KiB ${end}KiB" || return 1
+                               fi
+                               msg "Resize Complete" "\n$part has been successfully resized to $((size / 1024))M.\n" 1
+                               ;;
+                       "") msg "No Filesystem" "\nFor unformatted partitions, cfdisk can be used in the partition menu.\n" ;;
+                       *) msg "Invalid Filesystem: $fs" "\nResizing only supports ext and ntfs.\n" ;;
+               esac
+       fi
+}
+
+###############################################################################
+# partition management functions
+# these are helpers for use by other functions to do essential setup/teardown
+
 part_find()
 {
        local regexp="$1" err=''
@@ -877,13 +769,28 @@ part_find()
        return 0
 }
 
+part_swap()
+{
+       if [[ $1 == "$MNT/swapfile" && $SWAP_SIZE ]]; then
+               fallocate -l $SWAP_SIZE "$1" 2>$ERR
+               errshow "fallocate -l $SWAP_SIZE $1"
+               chmod 600 "$1" 2>$ERR
+               errshow "chmod 600 $1"
+       fi
+       mkswap "$1" >/dev/null 2>$ERR
+       errshow "mkswap $1"
+       swapon "$1" >/dev/null 2>$ERR
+       errshow "swapon $1"
+       return 0
+}
+
 part_mount()
 {
        local part="$1" mountp="${MNT}$2" fs=""
        fs="$(lsblk -lno FSTYPE "$part")"
        mkdir -p "$mountp"
 
-       if [[ $fs && ${FS_OPTS[$fs]} && $part != "$BOOT_PART" ]] && select_mntopts "$fs"; then
+       if [[ $fs && ${FS_OPTS[$fs]} && $part != "$BOOT_PART" && $part != "$AUTO_ROOT_PART" ]] && select_mntopts "$fs"; then
                mount -o "$MNT_OPTS" "$part" "$mountp" >/dev/null 2>&1
        else
                mount "$part" "$mountp" >/dev/null 2>&1
@@ -900,86 +807,12 @@ part_format()
        local part="$1" fs="$2" delay="$3"
 
        msg "Format" "\nFormatting $part as $fs\n" 0
-       ${FS_CMDS[$fs]} "$part" >/dev/null 2>$ERR
-       errshow "${FS_CMDS[$fs]} $part" || return 1
+       mkfs.$fs ${FS_CMD_FLAGS[$fs]} "$part" >/dev/null 2>$ERR
+       errshow "mkfs.$fs ${FS_CMD_FLAGS[$fs]} "$part"" || return 1
        FORMATTED+="$part "
        sleep "${delay:-0}"
 }
 
-part_shrink()
-{
-       part=""
-       typeset -i size num
-       local device="$1" fs=""
-
-       part_find "${device##*/}[^ ]" || return 1
-       (( COUNT == 1 )) && part="$(awk '{print $1}' <<< "${PARTS[@]}" )"
-       
-       if (( COUNT == 1 )) || dlg part menu "Resize" "\nWhich partition on $device do you want to resize?" $PARTS && [[ $part ]]; then
-               fs=$(lsblk -lno FSTYPE "$part")
-               case "$fs" in
-                       ext*|ntfs)
-                               msg "Resize" "\nGathering device size info.\n" 0
-
-                               # get device size info
-                               num="${part: -1}"
-                               end=$(parted -s "$device" unit KiB print | awk '/^\s*'"$num"'/ {print int($3)}')                    # part size in KiB
-                               devsize=$(parted -s "$device" unit KiB print | awk '/Disk '"${device//\//\\/}"':/ {print int($3)}') # whole device size in KiB
-
-                               # minimum in KiB (2^10)
-                               case "$fs" in
-                                       ext[2-4]) min=$(dumpe2fs -h "$part" |& awk '/Block count/{count=$NF} /Block size/{size=$NF} END{print int((count * size) / 1024)}') ;;
-                                       ntfs) min=$(ntfsresize -f -m "$part" | awk 'NR == 2 {print int(($NF * 1000 * 1000) / 1024)}') ;;
-                               esac
-
-                               # KiB -> MiB
-                               mbmin=$((min / 1024))
-                               mbend=$((end / 1024))
-
-                               # get new size from user
-                               tput cnorm
-                               if dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Resize: $part " --rangebox "$_resize" 17 "$COLUMNS" "$mbmin" "$mbend" $((mbend / 2)) 2>$ANS; then
-                                       (( (size = $(< "$ANS")) < mbend )) || return 1
-                                       size=$((size * 1024))
-                               else
-                                       return 1
-                               fi
-
-                               clear
-                               case "$fs" in
-                                       ext[2-4])
-                                               e2fsck -f "$part"; sleep 0.5
-                                               resize2fs -f "$part" ${size}K 2>$ERR # K=2^10 bytes
-                                               errshow "resize2fs -f $part ${size}K" || return 1
-                                               ;;
-                                       ntfs)
-                                               ntfsresize -fc "$part" || { msg "Resize" "\nThe ntfs partition $part cannot be resized because it is scheduled for a consistency check.\n\nTo do a consistency check in windows open command prompt as admin and run:\n\n\tchkdsk /f /r /x\n"; return 1; }
-                                               ntfsresize -ff --size $(( (size * 1024) / 1000 ))k "$part" 2>$ERR # k=10^3 bytes
-                                               errshow "ntfsresize -f -s $(( (size * 1024) / 1000 ))k $part" || return 1
-                                               ;;
-                               esac
-
-                               echo "filesystem shrunk successfully, now the partition"
-                               sleep 0.5
-                               parted "$device" resizepart "$num" ${size}KiB || return 1
-                               (( size++ ))
-                               sleep 0.5
-
-                               if [[ $devsize == "$end" ]]; then
-                                       parted -s "$device" mkpart primary ext4 ${size}KiB 100% 2>$ERR
-                                       errshow "parted -s $device mkpart primary ext4 ${size}KiB 100%" || return 1
-                               else
-                                       parted -s "$device" mkpart primary ext4 ${size}KiB ${end}KiB 2>$ERR
-                                       errshow "parted -s $device mkpart primary ext4 ${size}KiB ${end}KiB" || return 1
-                               fi
-
-                               msg "Resize Complete" "\n$part has been successfully resized to $((size / 1024))M.\n"
-                               ;;
-                       *) msg "Invalid Filesystem: $fs" "\nResizing only supports ext and ntfs.\n\nFor unformatted partitions, cfdisk can be used.\n" ;;
-               esac
-       fi
-}
-
 part_device()
 {
        if [[ $DEV_COUNT -eq 1 && $SYS_DEVS ]]; then
@@ -992,7 +825,8 @@ part_device()
                fi
                [[ $DEVICE ]] || return 1
        elif [[ $DEV_COUNT -lt 1 && ! $1 ]]; then
-               msg "Device Error" "\nNo available devices.\n\nExiting..\n" 2; die 1
+               msg "Device Error" "\nNo available devices.\n\nExiting..\n" 2
+               die 1
        fi
 
        [[ $1 ]] && BOOT_DEV="$DEVICE"
@@ -1022,7 +856,6 @@ part_cryptlv()
        if lsblk -lno TYPE "$part" | grep -q 'crypt'; then
                LUKS='encrypted'
                LUKS_NAME="${part#/dev/mapper/}"
-
                for dev in $(awk '/lvm/ && /crypto_LUKS/ {print "/dev/mapper/"$1}' <<< "$devs" | uniq); do
                        if lsblk -lno NAME "$dev" | grep -q "$LUKS_NAME"; then
                                LUKS_DEV="$LUKS_DEV cryptdevice=$dev:$LUKS_NAME"
@@ -1030,7 +863,6 @@ part_cryptlv()
                                break
                        fi
                done
-
                for dev in $(awk '/part/ && /crypto_LUKS/ {print "/dev/"$1}' <<< "$devs" | uniq); do
                        if lsblk -lno NAME "$dev" | grep -q "$LUKS_NAME"; then
                                LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$dev" | awk '/part/ && /crypto_LUKS/ {print $1}')"
@@ -1038,18 +870,15 @@ part_cryptlv()
                                break
                        fi
                done
-
        elif lsblk -lno TYPE "$part" | grep -q 'lvm'; then
                LVM='logical volume'
                VNAME="${part#/dev/mapper/}"
-
                for dev in $(awk '/crypt/ && /lvm2_member/ {print "/dev/mapper/"$1}' <<< "$devs" | uniq); do
                        if lsblk -lno NAME "$dev" | grep -q "$VNAME"; then
                                LUKS_NAME="${dev/\/dev\/mapper\//}"
                                break
                        fi
                done
-
                for dev in $(awk '/part/ && /crypto_LUKS/ {print "/dev/"$1}' <<< "$devs" | uniq); do
                        if lsblk -lno NAME "$dev" | grep -q "$LUKS_NAME"; then
                                LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$dev" | awk '/part/ && /crypto_LUKS/ {print $1}')"
@@ -1063,9 +892,9 @@ part_cryptlv()
 
 part_countdec()
 {
-       for i in "$@"; do
+       for pt; do
                if (( COUNT > 0 )); then
-                       PARTS="$(sed "/${i//\//\\/}/d" <<< "$PARTS")"
+                       PARTS="$(sed "/${pt//\//\\/}/d" <<< "$PARTS")"
                        (( COUNT-- ))
                fi
        done
@@ -1085,10 +914,13 @@ part_mountconf()
 
 ###############################################################################
 # mounting menus
+# mount_menu is the entry point which calls all other functions
+# once finished it returns to the main menu: main()
 
-select_menu()
+mount_menu()
 {
-       check_background_install || return 0
+       msg "Info" "\nGathering device info.\n" 0
+       no_bg_install || return 0
        lvm_detect
        umount_dir $MNT
        part_find 'part|lvm|crypt' || { SEL=2; return 1; }
@@ -1111,7 +943,7 @@ select_menu()
 
        select_swap || return 1
        select_extra_partitions || return 1
-       install_background || return 1
+       install_background
 
        return 0
 }
@@ -1175,6 +1007,7 @@ select_mountpoint()
                        EXMNT=''
                fi
        done
+       msg "Mount Extra" "\nMounting Finished\n\n\nNo extra partitions available to mount, returning to main menu.\n" 2
        return 0
 }
 
@@ -1184,8 +1017,11 @@ select_filesystem()
        local txt="\nSelect which filesystem to use for: $part\n\nDefault:  ext4"
        cur="$(lsblk -lno FSTYPE "$part" 2>/dev/null)"
 
+       # bail early if the partition was created in part_auto()
+       [[ $cur && $part == "$AUTO_ROOT_PART" ]] && return 0
+
        until [[ $fs ]]; do
-               if [[ $cur && ($part != "$ROOT_PART" || $FORMATTED == *"$part"*) ]]; then
+               if [[ $cur && $FORMATTED == *"$part"* ]]; then
                        dlg fs menu "Filesystem" "$txt\nCurrent:  $cur" skip - ext4 - ext3 - ext2 - vfat - ntfs - f2fs - jfs - xfs - nilfs2 - reiserfs - || return 1
                else
                        dlg fs menu "Filesystem" "$txt" ext4 - ext3 - ext2 - vfat - ntfs - f2fs - jfs - xfs - nilfs2 - reiserfs - || return 1
@@ -1198,18 +1034,33 @@ select_filesystem()
 
 select_efi_partition()
 {
-       if (( COUNT == 1 )); then
-               BOOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
-       elif [[ $AUTO_BOOT_PART ]]; then
-               BOOT_PART="$AUTO_BOOT_PART"
-               return 0 # were done here
-       else
-               dlg BOOT_PART menu "EFI Partition" "$_uefi" $PARTS
+       if [[ -z $BOOT_PART ]]; then
+               if [[ $AUTO_BOOT_PART ]]; then
+                       BOOT_PART="$AUTO_BOOT_PART"
+                       return 0 # were done here
+               else
+                       local pts size dev isize bsize ptcount=0
+
+                       # walk partition list and skip ones that are too small/big for boot
+                       while read -r dev size; do
+                               size_t="${size: -1:1}"  # size type eg. K, M, G, T
+                               isize=${size:0:-1}      # remove trailing size type character
+                               isize=${isize%.*}       # remove any decimal (round down)
+                               [[ $size_t =~ [KT] || ($size_t == 'G' && $isize -gt 2) || ($size_t == 'M' && $isize -lt 100) ]] || { pts+="$dev $size "; (( ptcount++ )); }
+                       done <<< "$PARTS"
+
+                       if (( ptcount == 1 )); then
+                               msg "EFI Boot Partition" "\nOnly one partition available that meets size requirements.\n" 1
+                               BOOT_PART="$(awk 'NF > 0 {print $1}' <<< "$pts")"
+                       else
+                               dlg BOOT_PART menu "EFI Partition" "$_uefi" $pts
+                       fi
+               fi
        fi
 
-       [[ $BOOT_PART ]] || return 1
-
-       if grep -q 'fat' <<< "$(fsck -N "$BOOT_PART")"; then
+       if [[ -z $BOOT_PART ]]; then
+               return 1
+       elif grep -q 'fat' <<< "$(fsck -N "$BOOT_PART")"; then
                local txt="\nIMPORTANT:\n\nThe EFI partition $BOOT_PART $_format"
                if yesno "Format EFI Partition" "$txt" "Format $BOOT_PART" "Skip Formatting" 1; then
                        part_format "$BOOT_PART" "vfat" 2
@@ -1223,14 +1074,29 @@ select_efi_partition()
 
 select_boot_partition()
 {
-       if [[ $AUTO_BOOT_PART && ! $LVM ]]; then
-               BOOT_PART="$AUTO_BOOT_PART"; return 0 # were done here
-       elif [[ $LUKS && ! $LVM ]]; then
-               dlg BOOT_PART menu "Boot Partition" "$_biosluks" $PARTS
-               [[ $BOOT_PART ]] || return 1
-       else
-               dlg BOOT_PART menu "Boot Partition" "$_bios" "skip" "don't use a separate boot" $PARTS
-               [[ -z $BOOT_PART || $BOOT_PART == "skip" ]] && { BOOT_PART=''; return 0; }
+       if [[ -z $BOOT_PART ]]; then
+               if [[ $AUTO_BOOT_PART && ! $LVM ]]; then
+                       BOOT_PART="$AUTO_BOOT_PART"
+                       return 0 # were done here
+               else
+                       local pts size dev isize bsize ptcount=0
+
+                       # walk partition list and skip ones that are too small/big for boot
+                       while read -r dev size; do
+                               size_t="${size: -1:1}"  # size type eg. K, M, G, T
+                               isize=${size:0:-1}      # remove trailing size type character
+                               isize=${isize%.*}       # remove any decimal (round down)
+                               [[ $size_t =~ [KT] || ($size_t == 'G' && $isize -gt 2) || ($size_t == 'M' && $isize -lt 100) ]] || { pts+="$dev $size "; (( ptcount++ )); }
+                       done <<< "$PARTS"
+
+                       if [[ $LUKS && ! $LVM ]]; then
+                               dlg BOOT_PART menu "Boot Partition" "$_biosluks" $pts
+                               [[ $BOOT_PART ]] || return 1
+                       else
+                               dlg BOOT_PART menu "Boot Partition" "$_bios" "skip" "don't use a separate boot" $pts
+                               [[ -z $BOOT_PART || $BOOT_PART == "skip" ]] && { BOOT_PART=''; return 0; }
+                       fi
+               fi
        fi
 
        if grep -q 'ext[34]' <<< "$(fsck -N "$BOOT_PART")"; then
@@ -1246,24 +1112,48 @@ select_boot_partition()
 
 select_root_partition()
 {
-       if [[ $AUTO_ROOT_PART && -z $LVM && -z $LUKS ]]; then
-               ROOT_PART="$AUTO_ROOT_PART"
-       elif (( COUNT == 1 )); then
-               ROOT_PART="$(awk 'NR==1 {print $1}' <<< "$PARTS")"
-       else
-               dlg ROOT_PART menu "Mount Root" "\nSelect the root (/) partition, this is where $DIST will be installed.\n\nDevices smaller than 8G will not be shown here." $PARTS
+       if [[ -z $ROOT_PART ]]; then
+               if [[ $AUTO_ROOT_PART && -z $LVM && -z $LUKS ]]; then
+                       ROOT_PART="$AUTO_ROOT_PART"
+                       msg "Mount Menu" "\nUsing partitions created during automatic format.\n" 2
+                       part_mount "$ROOT_PART" || { ROOT_PART=''; return 1; }
+                       return 0  # we're done here
+               else
+                       local pts size dev isize bsize ptcount=0
+
+                       # walk partition list and skip ones that are too small for / (root)
+                       while read -r dev size; do
+                               size_t="${size: -1:1}"  # size type eg. K, M, G, T
+                               isize=${size:0:-1}      # remove trailing size type character
+                               isize=${isize%.*}       # remove any decimal (round down)
+                               [[ $size_t =~ [MK] || ($size_t == 'G' && $isize -lt 4) ]] || { pts+="$dev $size "; (( ptcount++ )); }
+                       done <<< "$PARTS"
+
+                       if (( ptcount == 1 )); then  # only one available device
+                               msg "Root Partition (/)" "\nOnly one partition available that meets size requirements.\n" 2
+                               ROOT_PART="$(awk 'NF > 0 {print $1}' <<< "$pts")"
+                       else
+                               dlg ROOT_PART menu "Mount Root" "\nSelect the root (/) partition, this is where $DIST will be installed.\n\nDevices smaller than 8G will not be shown here." $pts
+                       fi
+               fi
        fi
-       [[ $ROOT_PART ]] || return 1
-
-       select_filesystem "$ROOT_PART" || { ROOT_PART=''; return 1; }
-       part_mount "$ROOT_PART" || { ROOT_PART=''; return 1; }
 
+       if [[ -z $ROOT_PART ]] || ! select_filesystem "$ROOT_PART" || ! part_mount "$ROOT_PART"; then
+               ROOT_PART=''
+               return 1
+       fi
        return 0
 }
 
 select_extra_partitions()
 {
-       local part
+       local part size dev
+
+       # walk partition list and skip ones that are too small to be usable
+       while read -r dev size; do
+               [[ ${size: -1:1} =~ [KM] ]] && part_countdec "$dev"
+       done <<< "$PARTS"
+
        while (( COUNT > 0 )); do
                part=''
                dlg part menu 'Mount Extra' "$_expart" 'done' 'finish mounting step' $PARTS || break
@@ -1281,11 +1171,11 @@ select_extra_partitions()
 
 ###############################################################################
 # installation
+# main is the entry point which calls all other install functions, once
+# complete it shows a dialog to edit files on the new system before reboot
 
 install_main()
 {
-       clear
-       tput cnorm
        install_base
        genfstab -U $MNT >$MNT/etc/fstab 2>$ERR
        errshow 1 "genfstab -U $MNT >$MNT/etc/fstab"
@@ -1295,11 +1185,10 @@ install_main()
        install_boot
        chrun "hwclock --systohc --utc" || chrun "hwclock --systohc --utc --directisa"
        install_user
-       install_xinit
+       install_login
        chrun "chown -Rf $NEWUSER:users /home/$NEWUSER"
-       sleep 1
 
-       while true; do
+       while :; do
                dlg choice menu "Finalization" "$_edit" \
                        finished   "exit the installer and reboot" \
                        keyboard   "${EDIT_FILES[keyboard]}" \
@@ -1315,15 +1204,15 @@ install_main()
                        login      "${EDIT_FILES[login]}"
 
                if [[ -z $choice || $choice == 'finished' ]]; then
-                       [[ $DEBUG == true && -r $DBG ]] && vim $DBG
-                       die 127
+                       [[ $DEBUG == true && -r $DBG ]] && ${EDITOR:-vim} $DBG
+                       clear && die 127
                else
                        local exists=''
                        for f in ${EDIT_FILES[$choice]}; do
                                [[ -e ${MNT}$f ]] && exists+=" ${MNT}$f"
                        done
                        if [[ $exists ]]; then
-                               vim -O $exists
+                               ${EDITOR:-vim} -O $exists
                        else
                                msg "File Missing" "\nThe file(s) selected do not exist:\n\n${EDIT_FILES[$choice]}\n"
                        fi
@@ -1333,90 +1222,78 @@ install_main()
 
 install_base()
 {
-       if [[ $RSYNC_PID || $MIRROR_PID ]]; then
-               while kill -0 "$RSYNC_PID" 2>/dev/null || kill -0 "$MIRROR_PID" 2>/dev/null; do
-                       clear; printf "\nOne or more background install processes are still running...\n"; sleep 1
-               done
-               trap - EXIT
-               unset RSYNC_PID MIRROR_PID
-       elif [[ -d /run/archiso/sfs/airootfs/etc/skel ]]; then
-               rsync -ahv /run/archiso/sfs/airootfs/ $MNT/ 2>$ERR
-               errshow 1 "rsync -ahv /run/archiso/sfs/airootfs/ $MNT/"
-               install_mirrorlist "$MNT/etc/pacman.d/mirrorlist"
-               chrun "pacman -Syyu --noconfirm && pacman -S $BASE_PKGS --needed --noconfirm"
-       else
-               mkdir -p /etc/pacman.d/mirrorlist
-               install_mirrorlist "/etc/pacman.d/mirrorlist"
-               pacstrap $MNT base $ISO_BASE 2>$ERR
-               errshow 1 "pacstrap $MNT base $KERNEL $ISO_BASE"
-               mkdir -p $MNT/etc/pacman.d/mirrorlist
-               cp -f "/etc/pacman.d/mirrorlist" "$MNT/etc/pacman.d/mirrorlist"
-               chrun "pacman -Syyu --noconfirm && pacman -S $BASE_PKGS --needed --noconfirm"
-       fi
+       clear
+       tput cnorm
+       while kill -0 $BG_PID 2>/dev/null; do
+               clear; printf "\nA background install process is still running...\n"; sleep 1
+       done
+       trap - EXIT
+       unset BG_PID
 
        rm -rf $MNT/etc/mkinitcpio-archiso.conf
        find $MNT/usr/lib/initcpio -name 'archiso*' -type f -delete
-       sed -i 's/volatile/auto/g' $MNT/etc/systemd/journald.conf
+       sed -i 's/#\(Storage=\)volatile/\1auto/' $MNT/etc/systemd/journald.conf
        find $MNT/boot -name '*-ucode.img' -delete
 
+       [[ $DIST != "ArchLabs" ]] || sed -i "s/ArchLabs/$DIST/g" $MNT/etc/{lsb-release,os-release}
+
        if [[ $VM ]]; then
                find $MNT/etc/X11/xorg.conf.d/ -name '*.conf' -delete
        elif lspci | grep ' VGA ' | grep -q 'Intel'; then
-               cat > $MNT/etc/X11/xorg.conf.d/20-intel.conf << EOF
-Section "Device"
-       Identifier  "Intel Graphics"
-       Driver      "intel"
-       Option      "TearFree" "true"
-EndSection
-EOF
-       fi
-
-       [[ -e /run/archiso/sfs/airootfs && $KERNEL == 'linux' ]] && cp -vf $RUN/x86_64/vmlinuz $MNT/boot/vmlinuz-linux
-
-       cp -fv /etc/resolv.conf $MNT/etc/
+               echo "Creating Intel VGA Tear Free config /etc/X11/xorg.conf.d/20-intel.conf"
+               cat > $MNT/etc/X11/xorg.conf.d/20-intel.conf <<- EOF
+               Section "Device"
+                   Identifier  "Intel Graphics"
+                   Driver      "intel"
+                   Option      "TearFree" "true"
+               EndSection
+               EOF
+       fi
+
+       [[ -e /run/archiso/sfs/airootfs ]] && cp -vf $RUN/x86_64/vmlinuz $MNT/boot/vmlinuz-linux
+       [[ -d /etc/netctl ]] && cp -rfv /etc/netctl $MNT/etc/
+       [[ -f /etc/resolv.conf ]] && cp -fv /etc/resolv.conf $MNT/etc/
        [[ -e /etc/NetworkManager/system-connections ]] && cp -rvf /etc/NetworkManager/system-connections $MNT/etc/NetworkManager/
 
        echo "LANG=$MYLOCALE" > $MNT/etc/locale.conf
-       cp -f $MNT/etc/locale.conf $MNT/etc/default/locale
+       cp -fv $MNT/etc/locale.conf $MNT/etc/default/locale
        sed -i "s/#en_US.UTF-8/en_US.UTF-8/g; s/#${MYLOCALE}/${MYLOCALE}/g" $MNT/etc/locale.gen
        chrun "locale-gen"
        chrun "ln -svf /usr/share/zoneinfo/$ZONE/$SUBZ /etc/localtime"
 
-       if [[ $BROADCOM_WL ]]; then
-               echo 'blacklist bcma' >> $MNT/etc/modprobe.d/blacklist.conf
-               rm -f $MNT/etc/modprobe/
-       fi
-
-       cat > $MNT/etc/X11/xorg.conf.d/00-keyboard.conf << EOF
-# Use localectl(1) to instruct systemd-localed to update it.
-Section "InputClass"
-       Identifier      "system-keyboard"
-       MatchIsKeyboard "on"
-       Option          "XkbLayout" "$KEYMAP"
-EndSection
-EOF
-       cat > $MNT/etc/default/keyboard << EOF
-# KEYBOARD CONFIGURATION FILE
-# Consult the keyboard(5) manual page.
-XKBMODEL=""
-XKBLAYOUT="$KEYMAP"
-XKBVARIANT=""
-XKBOPTIONS=""
-BACKSPACE="guess"
-EOF
+       cat > $MNT/etc/X11/xorg.conf.d/00-keyboard.conf <<- EOF
+       # Use localectl(1) to instruct systemd-localed to update it.
+       Section "InputClass"
+           Identifier      "system-keyboard"
+           MatchIsKeyboard "on"
+           Option          "XkbLayout" "$KEYMAP"
+       EndSection
+       EOF
+
+       cat > $MNT/etc/default/keyboard <<- EOF
+       # KEYBOARD CONFIGURATION FILE
+       # Consult the keyboard(5) manual page.
+       XKBMODEL=""
+       XKBLAYOUT="$KEYMAP"
+       XKBVARIANT=""
+       XKBOPTIONS=""
+       BACKSPACE="guess"
+       EOF
        printf "KEYMAP=%s\nFONT=%s\n" "$CMAP" "$FONT" > $MNT/etc/vconsole.conf
        echo "$MYHOST" > $MNT/etc/hostname
-       cat > $MNT/etc/hosts << EOF
-127.0.0.1      localhost
-127.0.1.1      $MYHOST
-::1                    localhost ip6-localhost ip6-loopback
-ff02::1                ip6-allnodes
-ff02::2                ip6-allrouters
-EOF
+       cat > $MNT/etc/hosts <<- EOF
+       127.0.0.1       localhost
+       127.0.1.1       $MYHOST
+       ::1                     localhost ip6-localhost ip6-loopback
+       ff02::1         ip6-allnodes
+       ff02::2         ip6-allrouters
+       EOF
 }
 
 install_boot()
 {
+       echo "Installing $BOOTLDR"
+
        if [[ $ROOT_PART == /dev/mapper* ]]; then
                ROOT_PART_ID="$ROOT_PART"
        else
@@ -1426,8 +1303,9 @@ install_boot()
        fi
 
        if [[ $SYS == 'UEFI' ]]; then
+               # remove our old install and generic BOOT/ dir
                find $MNT/$BOOTDIR/EFI/ -maxdepth 1 -mindepth 1 -iname "$DIST" -type d -delete
-               find $MNT/$BOOTDIR/EFI/ -maxdepth 1 -mindepth 1 -iname 'boot' -type d -delete
+               find $MNT/$BOOTDIR/EFI/ -maxdepth 1 -mindepth 1 -iname 'BOOT' -type d -delete
        fi
 
        prerun_$BOOTLDR
@@ -1435,23 +1313,20 @@ install_boot()
        errshow 1 "${BCMDS[$BOOTLDR]}"
 
        if [[ -d $MNT/hostrun ]]; then
-               umount $MNT/hostrun/udev >/dev/null 2>&1
-               umount $MNT/hostrun/lvm >/dev/null 2>&1
+               # cleanup the bind mounts we made earlier for the grub-probe module
+               umount_dir $MNT/hostrun/{udev,lvm}
                rm -rf $MNT/hostrun >/dev/null 2>&1
        fi
 
        if [[ $SYS == 'UEFI' ]]; then
                # some UEFI firmware requires a generic esp/BOOT/BOOTX64.EFI
                mkdir -pv $MNT/$BOOTDIR/EFI/BOOT
-               if [[ $BOOTLDR == 'grub' ]]; then
-                       cp -fv $MNT/$BOOTDIR/EFI/$DIST/grubx64.efi $MNT/$BOOTDIR/EFI/BOOT/BOOTX64.EFI
-               elif [[ $BOOTLDR == 'syslinux' ]]; then
-                       cp -rf $MNT/$BOOTDIR/EFI/syslinux/* $MNT/$BOOTDIR/EFI/BOOT/
-                       cp -f $MNT/$BOOTDIR/EFI/syslinux/syslinux.efi $MNT/$BOOTDIR/EFI/BOOT/BOOTX64.EFI
-               elif [[ $BOOTLDR == 'refind-efi' ]]; then
-                       sed -i '/#extra_kernel_version_strings/ c extra_kernel_version_strings linux-hardened,linux-zen,linux-lts,linux' $MNT/$BOOTDIR/EFI/refind/refind.conf
-                       cp -fv $MNT/$BOOTDIR/EFI/refind/refind_x64.efi $MNT/$BOOTDIR/EFI/BOOT/BOOTX64.EFI
-               fi
+               case "$BOOTLDR" in
+                       grub) cp -fv $MNT/$BOOTDIR/EFI/$DIST/grubx64.efi $MNT/$BOOTDIR/EFI/BOOT/BOOTX64.EFI ;;
+                       syslinux) cp -rf "$MNT/$BOOTDIR/EFI/syslinux/"* $MNT/$BOOTDIR/EFI/BOOT/ && cp -f $MNT/$BOOTDIR/EFI/syslinux/syslinux.efi $MNT/$BOOTDIR/EFI/BOOT/BOOTX64.EFI ;;
+                       refind-efi) sed -i '/#extra_kernel_version_strings/ c extra_kernel_version_strings linux-hardened,linux-zen,linux-lts,linux' $MNT/$BOOTDIR/EFI/refind/refind.conf
+                               cp -fv $MNT/$BOOTDIR/EFI/refind/refind_x64.efi $MNT/$BOOTDIR/EFI/BOOT/BOOTX64.EFI ;;
+               esac
        fi
 
        return 0
@@ -1459,97 +1334,132 @@ install_boot()
 
 install_user()
 {
+       rm -f $MNT/root/.zshrc  # remove welcome message from root zshrc
+
        chrun "chpasswd <<< 'root:$ROOT_PASS'" 2>$ERR
        errshow 1 "set root password"
-       if [[ $MYSHELL != *zsh ]]; then
-               chrun "usermod -s $MYSHELL root" 2>$ERR
-               errshow 1 "usermod -s $MYSHELL root"
-               [[ $MYSHELL == "/usr/bin/mksh" ]] && cp -fv $MNT/etc/skel/.mkshrc /root/.mkshrc
+       if [[ $MYSHELL != 'zsh' ]]; then # root uses zsh by default
+               chrun "usermod -s /bin/$MYSHELL root" 2>$ERR
+               errshow 1 "usermod -s /bin/$MYSHELL root"
+               # copy the default mkshrc to /root if it was selected
+               [[ $MYSHELL == 'mksh' ]] && cp -fv $MNT/etc/skel/.mkshrc $MNT/root/.mkshrc
        fi
 
-       local groups='audio,autologin,floppy,log,network,rfkill,scanner,storage,optical,power,wheel'
+       echo "Creating new user $NEWUSER and setting password"
+       local groups='audio,floppy,log,network,rfkill,scanner,storage,optical,power,wheel'
 
-       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 "useradd -m -u 1000 -g users -G $groups -s /bin/$MYSHELL $NEWUSER" 2>$ERR
+       errshow 1 "useradd -m -u 1000 -g users -G $groups -s /bin/$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
-               cp -fv $MNT/home/$NEWUSER/.vimrc $MNT/home/$NEWUSER/.config/nvim/init.vim
-               cp -rfv $MNT/home/$NEWUSER/.vim/colors $MNT/home/$NEWUSER/.config/nvim/colors
+       if [[ $INSTALL_WMS == *dwm* ]];then
+               mkdir -pv "$MNT/home/$NEWUSER/suckless"
+               for i in dwm dmenu st; do
+                       if chrun "git clone https://git.suckless.org/$i /home/$NEWUSER/suckless/$i"; then
+                               chrun "cd /home/$NEWUSER/suckless/$i; make prefix=/usr install; make clean"
+                       else
+                               printf "failed to clone %s repo\n" "$i"
+                       fi
+               done
+       fi
+
+       [[ $MYSHELL != 'bash' ]] && rm -rf "$MNT/home/$NEWUSER/.bash"*
+       [[ $MYSHELL != 'zsh' ]] && rm -rf "$MNT/home/$NEWUSER/.z"*
+
+       # remove some commands from ~/.xprofile when using KDE or Gnome as the login session
+       if [[ $LOGIN_WM =~ (startkde|gnome-session) || ($LOGIN_TYPE != 'xinit' && $WM_PKGS =~ (plasma|gnome)) ]]; then
+               sed -i '/super/d; /nitrogen/d; /compton/d' "$MNT/home/$NEWUSER/.xprofile" "$MNT/root/.xprofile"
+       elif [[ $LOGIN_WM == 'dwm' ]]; then # and dwm
+               sed -i '/super/d; /compton/d' "$MNT/home/$NEWUSER/.xprofile" "$MNT/root/.xprofile"
        fi
 
-       [[ $INSTALL_WMS == *dwm* ]] && install_suckless
-       [[ $LOGIN_WM =~ (startkde|gnome-session) ]] && sed -i '/super/d' $MNT/home/$NEWUSER/.xprofile /root/.xprofile
+       # create user home directories (Music, Documents, Downloads, etc..)
+       chrun 'xdg-user-dirs-update'
 
        return 0
 }
 
-install_xinit()
+install_login()
+{
+       local serv="$MNT/etc/systemd/system/getty@tty1.service.d"
+       echo "Setting up $LOGIN_TYPE"
+       case $LOGIN_TYPE in
+               ly|sddm|gdm|lightdm)
+                       if [[ $LOGIN_WM == *dwm* ]]; then # dwm doesn't include an xsession file for display managers
+                               mkdir -p $MNT/usr/share/xsessions
+                               cat >$MNT/usr/share/xsessions/dwm.desktop <<- EOF
+                               [Desktop Entry]
+                               Encoding=UTF-8
+                               Name=Dwm
+                               Comment=Dynamic Window Manager
+                               Exec=dwm
+                               Type=XSession
+                               EOF
+                       fi
+                       rm -rf "$serv" "$MNT/home/$NEWUSER/.xinitrc"
+                       chrun "systemctl enable $LOGIN_TYPE.service" 2>$ERR
+                       errshow 1 "systemctl enable $LOGIN_TYPE.service"
+                       ${LOGIN_TYPE}_config
+                       ;;
+               xinit)
+                       if [[ $INSTALL_WMS ]]; then
+                               sed -i "/exec/ c exec ${LOGIN_WM}" "$MNT/home/$NEWUSER/.xinitrc"
+                       elif [[ -e $MNT/home/$NEWUSER/.xinitrc ]]; then
+                               sed -i '/exec/d' "$MNT/home/$NEWUSER/.xinitrc"
+                               return 0
+                       fi
+                       if [[ $AUTOLOGIN ]]; then
+                               sed -i "s/root/${NEWUSER}/g" $serv/autologin.conf
+                               cat > "$MNT/home/$NEWUSER/$LOGINRC" <<- EOF
+                               # automatically run startx when logging in on tty1
+                               [ -z "\$DISPLAY" ] && [ \$XDG_VTNR -eq 1 ] && startx
+                               EOF
+                       else
+                               rm -rf $serv
+                       fi
+                       ;;
+       esac
+}
+
+install_packages()
 {
-       SERVICE="$MNT/etc/systemd/system/getty@tty1.service.d"
-       sed -i '/printf/d' $MNT/root/.zshrc
+       local rmpkg="archlabs-installer "
+       local inpkg="$PACKAGES $USER_PKGS $AL_BASE_PKGS "
 
-       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
+       if [[ $MYSHELL == 'zsh' ]]; then
+               inpkg+="zsh-completions "
        else
-               printf "exec %s\n" "$LOGIN_WM" >> $MNT/home/$NEWUSER/.xinitrc
+               rmpkg+="zsh "
        fi
 
-       [[ ${EDIT_FILES[login]} == *"$LOGINRC"* ]] || EDIT_FILES[login]+=" /home/$NEWUSER/$LOGINRC"
-
-       if [[ $AUTOLOGIN ]]; then
-               sed -i "s/root/${NEWUSER}/g" $SERVICE/autologin.conf
-               cat > $MNT/home/$NEWUSER/$LOGINRC <<EOF
-# ~/$LOGINRC
-# sourced by ${MYSHELL##*/} when used as a login shell
-
-# automatically run startx when logging in on tty1
-[[ -z \$DISPLAY && \$XDG_VTNR -eq 1 ]] && exec startx -- vt1
-EOF
+       if [[ $INSTALL_WMS == 'dwm' ]]; then # dwm only needs a very limited package set
+               inpkg+="nitrogen polkit-gnome gnome-keyring dunst "
        else
-               rm -rf $SERVICE
-               rm -rf $MNT/home/$NEWUSER/.{profile,zprofile,bash_profile}
+               [[ $INSTALL_WMS =~ (plasma|gnome|cinnamon) ]] || inpkg+="archlabs-ksuperkey "
+               [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps|fluxbox) ]] && inpkg+="$WM_BASE_PKGS "
+               [[ $inpkg =~ (term|plasma|rxvt|tilda|tilix|sakura) || $INSTALL_WMS =~ (gnome|plasma|xfce4) ]] || inpkg+="xterm "
        fi
-}
 
-install_packages()
-{
-       local rmpkg=""
-       local inpkg="$PACKAGES $USER_PKGS"
+       # update and install crucial packages first to avoid issues
+       chrun "pacman -Syyu $KERNEL $BASE_PKGS ${LOGIN_PKGS[$LOGIN_TYPE]} $MYSHELL --noconfirm --needed" 2>$ERR
+       errshow 1 "pacman -Syyu $KERNEL $BASE_PKGS ${LOGIN_PKGS[$LOGIN_TYPE]} $MYSHELL --noconfirm --needed"
 
-       if pacman -Qsq 'archlabs-installer' >/dev/null 2>&1; then
-               rmpkg+=" archlabs-installer"
-       elif [[ -e "$MNT/usr/bin/archlabs-installer" ]]; then
-               rm -f "$MNT/usr/bin/archlabs-installer"
-       fi
+       # remove the packages we don't want on the installed system
+       chrun "pacman -Rnsc $rmpkg --noconfirm"
+
+       # reinstalling iputils fixes the network issue for non-root users
+       chrun "pacman -S iputils $UCODE --noconfirm"
 
-       [[ $UCODE ]] && inpkg+=" $UCODE"
-       [[ $MYSHELL == *mksh ]] && inpkg+=" mksh"
-       [[ $KERNEL == 'linux' ]] || { inpkg+=" $KERNEL"; rmpkg+=" linux"; }
-       [[ $inpkg =~ (term|urxvt|tilix|alacritty|sakura|tilda|plasma|cinnamon) || $INSTALL_WMS == *dwm* ]] || inpkg+=" xterm"
-       [[ $MYSHELL == '/usr/bin/zsh' ]] && inpkg+=" zsh-completions"
-       [[ $INSTALL_WMS =~ ^(plasma|gnome|cinnamon)$ ]] || inpkg+=" archlabs-ksuperkey"
-       [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps|dwm|fluxbox) ]] && inpkg+=" $WM_BASE_PKGS"
-
-       chrun "pacman -Syyu --noconfirm"
-       [[ $rmpkg ]] && chrun "pacman -Rns $rmpkg --noconfirm"
-       chrun "pacman -S iputils --noconfirm"
-       chrun "pacman -Q xorg-xinit 2>/dev/null || pacman -S $BASE_PKGS --needed --noconfirm"
+       # install the packages chosen throughout the install
        chrun "pacman -S $inpkg --needed --noconfirm" 2>$ERR
        errshow 1 "pacman -S $inpkg --needed --noconfirm"
 
+       # bootloader packages
        if [[ $BOOTLDR == 'grub' ]]; then
-               if [[ $SYS == 'BIOS' ]]; then
-                       chrun "pacman -S grub os-prober --needed --noconfirm" 2>$ERR
-                       errshow 1 "pacman -S grub os-prober --needed --noconfirm"
-               else
-                       chrun "pacman -S grub os-prober efibootmgr --needed --noconfirm" 2>$ERR
-                       errshow 1 "pacman -S grub os-prober efibootmgr --needed --noconfirm"
-               fi
+               [[ $SYS == 'UEFI' ]] && local efib="efibootmgr"
+               chrun "pacman -S os-prober grub $efib --needed --noconfirm" 2>$ERR
+               errshow 1 "pacman -S os-prober grub $efib --needed --noconfirm"
        elif [[ $BOOTLDR == 'refind-efi' ]]; then
                chrun "pacman -S refind-efi efibootmgr --needed --noconfirm" 2>$ERR
                errshow 1 "pacman -S refind-efi efibootmgr --needed --noconfirm"
@@ -1557,37 +1467,16 @@ install_packages()
                chrun "pacman -S efibootmgr --needed --noconfirm" 2>$ERR
                errshow 1 "pacman -S efibootmgr --needed --noconfirm"
        fi
-       sed -i "s/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g" $MNT/etc/sudoers
-       return 0
-}
-
-install_suckless()
-{
-       mkdir -pv $MNT/home/$NEWUSER/suckless
 
-       for i in dwm dmenu st; do
-               if chrun "git clone https://git.suckless.org/$i /home/$NEWUSER/suckless/$i"; then
-                       chrun "cd /home/$NEWUSER/suckless/$i; make PREFIX=/usr install; make clean; rm config.h"
-               else
-                       printf "failed to clone %s repo\n" "$i"
-               fi
-       done
+       # allow members of the wheel group to run commands as root
+       sed -i "s/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g" $MNT/etc/sudoers
 
-       if [[ -d $MNT/home/$NEWUSER/suckless/dwm && -x $MNT/usr/bin/dwm ]]; then
-               printf "To configure dwm edit %s\n" "/home/$NEWUSER/suckless/dwm/config.h"
-               printf "You can then recompile it with 'sudo make clean install'\n"
-               sleep 2
-       fi
+       return 0
 }
 
 install_mkinitcpio()
 {
        local add=''
-
-       # luks keyfile creation
-       # currently not used due to not prompting for passphrase on startup
-       # [[ $LUKS_UUID && $LUKS_PASS && $SYS == 'UEFI' && $BOOTLDR == 'grub' ]] && luks_keyfile
-
        [[ $LUKS ]] && add="encrypt"
        [[ $LVM ]] && { [[ $add ]] && add+=" lvm2" || add+="lvm2"; }
        sed -i "s/block filesystems/block ${add} filesystems ${HOOKS}/g" $MNT/etc/mkinitcpio.conf
@@ -1597,40 +1486,77 @@ install_mkinitcpio()
 
 install_mirrorlist()
 {
-       mfile="$1"
-
        if hash reflector >/dev/null 2>&1; then
-               reflector --score 120 -l 50 -f 5 --sort rate --save "$mfile"
+               reflector --verbose --score 80 -l 40 -f 5 --sort rate --save "$1"
        elif hash rankmirrors >/dev/null 2>&1; then
-               i="$(json 'ip' "check&?access_key=5f29642060ab983b31fdf4c2935d8c56&fields=ip")"
-               c="$(json 'country_code' "${i}?access_key=5f29642060ab983b31fdf4c2935d8c56&fields=country_code")"
-               if [[ $c && $c =~ (CA|US) ]]; then
-                       m="https://www.archlinux.org/mirrorlist/?country=US&country=CA&use_mirror_status=on"
-               elif [[ $c ]]; then
-                       m="https://www.archlinux.org/mirrorlist/?country=${c}&use_mirror_status=on"
-               else
-                       m="https://www.archlinux.org/mirrorlist/?country=US&country=CA&country=NZ&country=GB&country=AU&use_mirror_status=on"
+               echo "Sorting mirrorlist"
+               local key="access_key=5f29642060ab983b31fdf4c2935d8c56"
+               ip_add="$(curl -fsSL "http://api.ipstack.com/check&?$key&fields=ip" | python -c "import sys, json; print(json.load(sys.stdin)['ip'])")"
+               country="$(curl -fsSL "http://api.ipstack.com/$ip_add?$key&fields=country_code" | python -c "import sys, json; print(json.load(sys.stdin)['country_code'])")"
+               if [[ "$country" ]]; then
+                       if [[ $country =~ (CA|US) ]]; then
+                               # use both CA and US mirrors for CA or US countries
+                               mirror="https://www.archlinux.org/mirrorlist/?country=US&country=CA&use_mirror_status=on"
+                       elif [[ $country =~ (AU|NZ) ]]; then
+                               # use both AU and NZ mirrors for AU or NZ countries
+                               mirror="https://www.archlinux.org/mirrorlist/?country=AU&country=NZ&use_mirror_status=on"
+                       else
+                               mirror="https://www.archlinux.org/mirrorlist/?country=${country}&use_mirror_status=on"
+                       fi
+               else # no country code so just grab all mirrors, will be a very slow sort but we don't have other options
+                       mirror="https://www.archlinux.org/mirrorlist/?country=all&use_mirror_status=on"
                fi
-               curl -s "$m" | sed -e 's/^#Server/Server/' -e '/^#/d' | rankmirrors -t -n 10 - | tail -n 10 >"$mfile"
+               curl -fsSL "$mirror" | sed -e 's/^#Server/Server/' -e '/^#/d' | rankmirrors -n 6 - >"$1"
        fi
+
        return 0
 }
 
 install_background()
 {
-       if [[ -d /run/archiso/sfs/airootfs/etc/skel ]] && grep -qw "$MNT" /proc/mounts && (grep -qw "$MNT/$BOOTDIR" /proc/mounts || [[ $SYS == 'BIOS' && -z $LUKS ]]); then
-               yesno "Background Install" "\nSome parts of the install can be done in the background now, base unpack, mirrorlist sort, system update, and base packages.\n\nDo you want to start the background process?\n" || return 0
-               rsync -a /run/archiso/sfs/airootfs/ $MNT/ &
-               RSYNC_PID=$!
-               ( install_mirrorlist "$MNT/etc/pacman.d/mirrorlist" && chrun "pacman -Syyu $BASE_PKGS --needed --noconfirm" ) &
-               MIRROR_PID=$!
-               trap "kill $RSYNC_PID 2>/dev/null; kill $MIRROR_PID 2>/dev/null" EXIT
-       fi
-       return 0
+       ( rsync -a /run/archiso/sfs/airootfs/ $MNT/ && install_mirrorlist "$MNT/etc/pacman.d/mirrorlist" >/dev/null 2>&1 ) &
+       BG_PID=$!
+       trap "kill $BG_PID 2>/dev/null" EXIT
+}
+
+###############################################################################
+# display manager config
+# these are called based on which DM is chosen after it is installed
+# additional config can be  handled here, for now only lightdm has one
+
+lightdm_config()
+{
+       cat > $MNT/etc/lightdm/lightdm-gtk-greeter.conf <<- EOF
+       [greeter]
+       default-user-image=/usr/share/icons/ArchLabs-Dark/64x64/places/distributor-logo-archlabs.png
+       background=/usr/share/backgrounds/archlabs/archlabs.jpg
+       theme-name=Adwaita-dark
+       icon-theme-name=Adwaita
+       font-name=DejaVu Sans Mono 11
+       position=30%,end 50%,end
+       EOF
+}
+
+ly_config()
+{
+       :
+}
+
+gdm_config()
+{
+       :
+}
+
+sddm_config()
+{
+       :
 }
 
 ###############################################################################
 # bootloader setup
+# prerun_* set up the configs needed before actually running the commands
+# setup_* are run after selecting a bootloader and build the command used later
+# they can also be used for further user input as these run before control is taken away
 
 setup_grub()
 {
@@ -1640,9 +1566,6 @@ setup_grub()
                [[ $BOOT_DEV ]] || { part_device 1 || return 1; }
                BCMDS[grub]="grub-install --recheck --force --target=i386-pc $BOOT_DEV"
        else
-               if [[ $ROOT_PART == */dev/mapper/* && -z $LVM && -z $LUKS_PASS ]]; then
-                       luks_pass "$_luksopen" 1 || return 1
-               fi
                BCMDS[grub]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
                grub-install --recheck --force --target=x86_64-efi --efi-directory=/$BOOTDIR --bootloader-id=$DIST"
                grep -q /sys/firmware/efi/efivars /proc/mounts || mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
@@ -1660,14 +1583,11 @@ setup_grub()
 
 prerun_grub()
 {
-       sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g;
-       s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" $MNT/etc/default/grub
+       sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g; s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" $MNT/etc/default/grub
 
        if [[ $LUKS_DEV ]]; then
-               sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g;
-               s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" $MNT/etc/default/grub 2>$ERR
-               errshow 1 "sed -i 's~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g;
-               s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g' $MNT/etc/default/grub"
+               sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g; s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" $MNT/etc/default/grub 2>$ERR
+               errshow 1 "sed -i 's~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g; s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g' $MNT/etc/default/grub"
        fi
 
        if [[ $SYS == 'BIOS' && $LVM && -z $SEP_BOOT ]]; then
@@ -1676,8 +1596,7 @@ prerun_grub()
        fi
 
        # setup for os-prober module
-       mkdir -p /run/{lvm,udev}
-       mkdir -p $MNT/hostrun/{lvm,udev}
+       mkdir -p /run/{lvm,udev} $MNT/hostrun/{lvm,udev}
        mount --bind /run/lvm $MNT/hostrun/lvm
        mount --bind /run/udev $MNT/hostrun/udev
 
@@ -1694,7 +1613,6 @@ prerun_efistub()
        BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
                efibootmgr -v -d $BOOT_DEV -p $BOOT_PART_NUM -c -L '${DIST} Linux' -l /vmlinuz-${KERNEL} \
                -u 'root=$ROOT_PART_ID rw $([[ $UCODE ]] && printf 'initrd=\%s.img ' "$UCODE")initrd=\initramfs-${KERNEL}.img'"
-       return 0
 }
 
 setup_syslinux()
@@ -1705,139 +1623,106 @@ setup_syslinux()
                EDIT_FILES[bootloader]="/boot/EFI/syslinux/syslinux.cfg"
                BCMDS[syslinux]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
                efibootmgr -v -c -d $BOOT_DEV -p $BOOT_PART_NUM -l /EFI/syslinux/syslinux.efi -L $DIST"
-
        fi
 }
 
 prerun_syslinux()
 {
        local c="$MNT/boot/syslinux" s="/usr/lib/syslinux/bios" d=".."
-       [[ $SYS == 'UEFI' ]] && { c="$MNT/boot/EFI/syslinux"; s="/usr/lib/syslinux/efi64/"; d=''; }
-
-       mkdir -pv "$c" && cp -rfv $s/* "$c/" && cp -f "$RUN/syslinux/splash.png" "$c/"
-       cat > "$c/syslinux.cfg" << EOF
-UI vesamenu.c32
-MENU TITLE $DIST Boot Menu
-MENU BACKGROUND splash.png
-TIMEOUT 50
-DEFAULT $DIST
-
-# see: https://www.syslinux.org/wiki/index.php/Comboot/menu.c32
-MENU WIDTH 78
-MENU MARGIN 4
-MENU ROWS 4
-MENU VSHIFT 10
-MENU TIMEOUTROW 13
-MENU TABMSGROW 14
-MENU CMDLINEROW 14
-MENU HELPMSGROW 16
-MENU HELPMSGENDROW 29
-MENU COLOR border       30;44   #40ffffff #a0000000 std
-MENU COLOR title        1;36;44 #9033ccff #a0000000 std
-MENU COLOR sel          7;37;40 #e0ffffff #20ffffff all
-MENU COLOR unsel        37;44   #50ffffff #a0000000 std
-MENU COLOR help         37;40   #c0ffffff #a0000000 std
-MENU COLOR timeout_msg  37;40   #80ffffff #00000000 std
-MENU COLOR timeout      1;37;40 #c0ffffff #00000000 std
-MENU COLOR msg07        37;40   #90ffffff #a0000000 std
-MENU COLOR tabmsg       31;40   #30ffffff #00000000 std
-
-LABEL $DIST
-MENU LABEL $DIST Linux
-LINUX $d/vmlinuz-$KERNEL
-APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
-INITRD $([[ $UCODE ]] && printf "%s" "$d/$UCODE.img,")$d/initramfs-$KERNEL.img
-
-LABEL ${DIST}fallback
-MENU LABEL $DIST Linux Fallback
-LINUX $d/vmlinuz-$KERNEL
-APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
-INITRD $([[ $UCODE ]] && printf "%s" "$d/$UCODE.img,")$d/initramfs-$KERNEL-fallback.img
-$([[ $SYS == 'BIOS' ]] && printf "\n%s" "# examples of chainloading other bootloaders
-
-#LABEL grub2
-#MENU LABEL Grub2
-#COM32 chain.c32
-#APPEND file=$d/grub/boot.img
-
-#LABEL windows
-#MENU LABEL Windows
-#COM32 chain.c32
-#APPEND hd0 3")
-EOF
+       [[ $SYS == 'UEFI' ]] && { c="$MNT/boot/EFI/syslinux"; s="/usr/lib/syslinux/efi64"; d=''; }
+
+       mkdir -pv "$c"
+       cp -rfv "$s/"* "$c/"
+       cat > "$c/syslinux.cfg" <<- EOF
+       UI menu.c32
+       PROMPT 0
+       MENU TITLE $DIST Boot Menu
+       TIMEOUT 50
+       DEFAULT $DIST
+
+       LABEL $DIST
+       MENU LABEL $DIST Linux
+       LINUX $d/vmlinuz-$KERNEL
+       APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
+       INITRD $([[ $UCODE ]] && printf "%s" "$d/$UCODE.img,")$d/initramfs-$KERNEL.img
+
+       LABEL ${DIST}fallback
+       MENU LABEL $DIST Linux Fallback
+       LINUX $d/vmlinuz-$KERNEL
+       APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
+       INITRD $([[ $UCODE ]] && printf "%s" "$d/$UCODE.img,")$d/initramfs-$KERNEL-fallback.img
+       EOF
        return 0
 }
 
 setup_refind-efi()
 {
        EDIT_FILES[bootloader]="/boot/refind_linux.conf"
-       BCMDS[refind-efi]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
-               refind-install"
+       BCMDS[refind-efi]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1; refind-install"
 }
 
 prerun_refind-efi()
 {
-       cat > $MNT/boot/refind_linux.conf << EOF
-"$DIST Linux"          "root=$ROOT_PART_ID $([[ $LUKS_DEV ]] &&
-                        printf "%s " "$LUKS_DEV")rw add_efi_memmap $([[ $UCODE ]] &&
-                        printf "initrd=%s " "/$UCODE.img")initrd=/initramfs-$KERNEL.img"
-"$DIST Linux Fallback" "root=$ROOT_PART_ID $([[ $LUKS_DEV ]] &&
-                        printf "%s " "$LUKS_DEV")rw add_efi_memmap $([[ $UCODE ]] &&
-                        printf "initrd=%s " "/$UCODE.img")initrd=/initramfs-$KERNEL-fallback.img"
-EOF
+       cat > $MNT/boot/refind_linux.conf <<- EOF
+       "$DIST Linux"          "root=$ROOT_PART_ID $([[ $LUKS_DEV ]] &&
+                                               printf "%s " "$LUKS_DEV")rw add_efi_memmap $([[ $UCODE ]] &&
+                                               printf "initrd=%s " "/$UCODE.img")initrd=/initramfs-$KERNEL.img"
+       "$DIST Linux Fallback" "root=$ROOT_PART_ID $([[ $LUKS_DEV ]] &&
+                                               printf "%s " "$LUKS_DEV")rw add_efi_memmap $([[ $UCODE ]] &&
+                                               printf "initrd=%s " "/$UCODE.img")initrd=/initramfs-$KERNEL-fallback.img"
+       EOF
        mkdir -p $MNT/etc/pacman.d/hooks
-       cat > $MNT/etc/pacman.d/hooks/refind.hook << EOF
-[Trigger]
-Operation = Upgrade
-Type = Package
-Target = refind-efi
+       cat > $MNT/etc/pacman.d/hooks/refind.hook <<- EOF
+       [Trigger]
+       Operation = Upgrade
+       Type = Package
+       Target = refind-efi
 
-[Action]
-Description = Updating rEFInd on ESP
-When = PostTransaction
-Exec = /usr/bin/refind-install
-EOF
+       [Action]
+       Description = Updating rEFInd on ESP
+       When = PostTransaction
+       Exec = /usr/bin/refind-install
+       EOF
 }
 
 setup_systemd-boot()
 {
        EDIT_FILES[bootloader]="/boot/loader/entries/$DIST.conf"
-       BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
-               bootctl --path=/boot install"
+       BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1; bootctl --path=/boot install"
 }
 
 prerun_systemd-boot()
 {
        mkdir -p $MNT/boot/loader/entries
-       cat > $MNT/boot/loader/loader.conf << EOF
-default  $DIST
-timeout  5
-editor   no
-EOF
-       cat > $MNT/boot/loader/entries/$DIST.conf << EOF
-title   $DIST Linux
-linux   /vmlinuz-${KERNEL}$([[ $UCODE ]] && printf "\ninitrd  %s" "/$UCODE.img")
-initrd  /initramfs-$KERNEL.img
-options root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
-EOF
-       cat > $MNT/boot/loader/entries/$DIST-fallback.conf << EOF
-title   $DIST Linux Fallback
-linux   /vmlinuz-${KERNEL}$([[ $UCODE ]] && printf "\ninitrd  %s" "/$UCODE.img")
-initrd  /initramfs-$KERNEL-fallback.img
-options root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
-EOF
+       cat > $MNT/boot/loader/loader.conf <<- EOF
+       default  $DIST
+       timeout  5
+       editor   no
+       EOF
+       cat > $MNT/boot/loader/entries/$DIST.conf <<- EOF
+       title   $DIST Linux
+       linux   /vmlinuz-${KERNEL}$([[ $UCODE ]] && printf "\ninitrd  %s" "/$UCODE.img")
+       initrd  /initramfs-$KERNEL.img
+       options root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
+       EOF
+       cat > $MNT/boot/loader/entries/$DIST-fallback.conf <<- EOF
+       title   $DIST Linux Fallback
+       linux   /vmlinuz-${KERNEL}$([[ $UCODE ]] && printf "\ninitrd  %s" "/$UCODE.img")
+       initrd  /initramfs-$KERNEL-fallback.img
+       options root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
+       EOF
        mkdir -p $MNT/etc/pacman.d/hooks
-       cat > $MNT/etc/pacman.d/hooks/systemd-boot.hook << EOF
-[Trigger]
-Type = Package
-Operation = Upgrade
-Target = systemd
-
-[Action]
-Description = Updating systemd-boot
-When = PostTransaction
-Exec = /usr/bin/bootctl update
-EOF
+       cat > $MNT/etc/pacman.d/hooks/systemd-boot.hook <<- EOF
+       [Trigger]
+       Type = Package
+       Operation = Upgrade
+       Target = systemd
+
+       [Action]
+       Description = Updating systemd-boot
+       When = PostTransaction
+       Exec = /usr/bin/bootctl update
+       EOF
        systemd-machine-id-setup --root="$MNT"
        return 0
 }
@@ -1847,20 +1732,23 @@ EOF
 
 lvm_menu()
 {
-       check_background_install || return 1
+       msg "Info" "\nGathering device info.\n" 0
+       no_bg_install || return 1
        lvm_detect
        local choice
-       dlg choice menu "Logical Volume Management" "$_lvmmenu" \
-               "$_lvmnew"    "vgcreate -f, lvcreate -L -n" \
-               "$_lvmdel"    "vgremove -f" \
-               "$_lvmdelall" "lvrmeove, vgremove, pvremove -f" \
-               "back"        "return to the main menu"
-
-       case "$choice" in
-               "$_lvmnew") lvm_create || return 1 ;;
-               "$_lvmdel") lvm_delgroup && yesno "$_lvmdel" "$_lvmdelask" && vgremove -f "$DEL_VG" >/dev/null 2>&1 ;;
-               "$_lvmdelall") lvm_del_all ;;
-       esac
+       while :; do
+               dlg choice menu "Logical Volume Management" "$_lvmmenu" \
+                       "$_lvmnew"    "vgcreate -f, lvcreate -L -n" \
+                       "$_lvmdel"    "vgremove -f" \
+                       "$_lvmdelall" "lvrmeove, vgremove, pvremove -f" \
+                       "Back"        "Return to the main menu"
+               case "$choice" in
+                       "$_lvmnew") lvm_create && break ;;
+                       "$_lvmdel") lvm_delgroup && yesno "$_lvmdel" "$_lvmdelask" && vgremove -f "$DEL_VG" >/dev/null 2>&1 ;;
+                       "$_lvmdelall") lvm_del_all ;;
+                       *) break ;;
+               esac
+       done
 
        return 0
 }
@@ -1873,7 +1761,7 @@ lvm_detect()
        VGROUP="$(vgs -o vg_name --noheading 2>/dev/null)"
 
        if [[ $VGROUP && $v && $pv ]]; then
-               msg "Logical Volume Management" "\nActivating existing logical volume management (LVM).\n\n" 1
+               msg "LVM Setup" "\nActivating existing logical volume management.\n" 0
                modprobe dm-mod >/dev/null 2>$ERR
                errshow 'modprobe dm-mod'
                vgscan >/dev/null 2>&1
@@ -1887,10 +1775,11 @@ lvm_create()
        umount_dir $MNT
        lvm_mkgroup || return 1
        local txt="\nThe last (or only) logical volume will automatically use all remaining space in the volume group."
-       dlg VOL_COUNT menu "$_lvmnew" "\nSelect the number of logical volumes (LVs) to create in: $VGROUP\n$txt" 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9
+       dlg VOL_COUNT menu "$_lvmnew" "\nSelect the number of logical volumes (LVs) to create in: $VGROUP\n$txt" 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -
        [[ $VOL_COUNT ]] || return 1
        lvm_extra_lvs || return 1
        lvm_volume_name "$_lvmlvname\nNOTE: This LV will use up all remaining space in the volume group (${VGROUP_MB}MB)" || return 1
+       msg "$_lvmnew (LV:$VOL_COUNT)" "\nCreating volume $VNAME from remaining space in $VGROUP\n" 0
        lvcreate -l +100%FREE "$VGROUP" -n "$VNAME" >/dev/null 2>$ERR
        errshow "lvcreate -l +100%FREE $VGROUP -n $VNAME" || return 1
        LVM='logical volume'; sleep 0.5
@@ -1899,11 +1788,11 @@ lvm_create()
        return 0
 }
 
-get_lv_size()
+lvm_lv_size()
 {
        local txt="${VGROUP}: ${SIZE}$SIZE_UNIT (${VGROUP_MB}MB remaining).$_lvmlvsize"
 
-       while true; do
+       while :; do
                ERR_SIZE=0
                dlg VOLUME_SIZE input "$_lvmnew (LV:$VOL_COUNT)" "$txt" ''
                if [[ -z $VOLUME_SIZE ]]; then
@@ -1942,14 +1831,14 @@ get_lv_size()
 lvm_mkgroup()
 {
        local named=''
-       local txt="\nConfirm creation of volume group: $VGROUP\n\nwith the following partition(s):"
 
        until [[ $named ]]; do
                lvm_partitions || return 1
                lvm_group_name || return 1
-               yesno "$_lvmnew" "$txt $LVM_PARTS\n" && named=true
+               yesno "$_lvmnew" "\nCreate volume group: $VGROUP\n\nusing these partition(s): $LVM_PARTS\n" && named=true
        done
 
+       msg "$_lvmnew" "\nCreating volume group: $VGROUP\n" 0
        vgcreate -f "$VGROUP" $LVM_PARTS >/dev/null 2>$ERR
        errshow "vgcreate -f $VGROUP $LVM_PARTS" || return 1
 
@@ -1962,8 +1851,7 @@ lvm_mkgroup()
                VGROUP_MB=$SIZE
        fi
 
-       msg "$_lvmnew" "\nVolume group: $VGROUP ($SIZE $SIZE_UNIT) has been created\n"
-       return 0
+       msg "$_lvmnew" "\nVolume group $VGROUP (${SIZE}$SIZE_UNIT) successfully created\n"
 }
 
 lvm_del_all()
@@ -1994,6 +1882,7 @@ lvm_delgroup()
        for i in $(lvs --noheadings | awk '{print $2}' | uniq); do
                VOL_GROUP_LIST+="$i $(vgdisplay "$i" | awk '/VG Size/ {print $3$4}') "
        done
+
        [[ $VOL_GROUP_LIST ]] || { msg "No Groups" "\nNo volume groups found."; return 1; }
 
        dlg DEL_VG menu "Logical Volume Management" "\nSelect volume group to delete.\n\nAll logical volumes within will also be deleted." $VOL_GROUP_LIST
@@ -2003,7 +1892,8 @@ lvm_delgroup()
 lvm_extra_lvs()
 {
        while (( VOL_COUNT > 1 )); do
-               lvm_volume_name "$_lvmlvname" && get_lv_size || return 1
+               lvm_volume_name "$_lvmlvname" && lvm_lv_size || return 1
+               msg "$_lvmnew (LV:$VOL_COUNT)" "\nCreating a $VOLUME_SIZE volume $VNAME in $VGROUP\n" 0
                lvcreate -L "$VOLUME_SIZE" "$VGROUP" -n "$VNAME" >/dev/null 2>$ERR
                errshow "lvcreate -L $VOLUME_SIZE $VGROUP -n $VNAME" || return 1
                msg "$_lvmnew (LV:$VOL_COUNT)" "\nDone, logical volume (LV) $VNAME ($VOLUME_SIZE) has been created.\n"
@@ -2024,10 +1914,10 @@ lvm_group_name()
 {
        VGROUP=''
        until [[ $VGROUP ]]; do
-               dlg VGROUP input "$_lvmnew" "$_lvmvgname" "mygroup"
+               dlg VGROUP input "$_lvmnew" "$_lvmvgname" "lvgroup"
                if [[ -z $VGROUP ]]; then
                        return 1
-               elif [[ ${VGROUP:0:1} == "/" || $VGROUP =~ \ |\' ]] || lsblk | grep -q "$VGROUP"; then
+               elif [[ ${VGROUP:0:1} == "/" || $VGROUP =~ \ |\' ]] || vgdisplay | grep -q "$VGROUP"; then
                        msg "LVM Name Error" "$_lvmerrvgname"
                        VGROUP=''
                fi
@@ -2039,7 +1929,7 @@ lvm_volume_name()
 {
        VNAME=''
        local txt="$1" default="mainvolume"
-       (( VOL_COUNT > 1 )) && default="extravolume$VOL_COUNT"
+       (( VOL_COUNT > 1 )) && default="extvolume$VOL_COUNT"
        until [[ $VNAME ]]; do
                dlg VNAME input "$_lvmnew (LV:$VOL_COUNT)" "\n$txt" "$default"
                if [[ -z $VNAME ]]; then
@@ -2058,12 +1948,12 @@ lvm_volume_name()
 luks_menu()
 {
        local choice
-       check_background_install || return 1
+       no_bg_install || return 1
        dlg choice menu "LUKS Encryption" "$_luksmenu" \
                "$_luksnew"  "cryptsetup -q luksFormat" \
                "$_luksopen" "cryptsetup open --type luks" \
                "$_luksadv"  "cryptsetup -q -s -c luksFormat" \
-               "back"       "Return to the main menu"
+               "Back"       "Return to the main menu"
 
        case "$choice" in
                "$_luksnew") luks_basic || return 1 ;;
@@ -2089,7 +1979,7 @@ luks_open()
        [[ $LUKS_PART ]] || return 1
 
        luks_pass "$_luksopen" || return 1
-       msg "$_luksopen" "\nOpening encrypted partition: $LUKS_NAME\n\nDevice or volume used: $LUKS_PART\n" 0
+       msg "$_luksopen" "\nOpening encrypted partition: $LUKS_NAME\n\nUsing device/volume: $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" || return 1
        LUKS='encrypted'; luks_show
@@ -2099,49 +1989,26 @@ luks_open()
 luks_pass()
 {
        LUKS_PASS=''
-       local t="$1" op="$2" v='' p='' p2=''
+       local t="$1"
+       typeset -a ans=(cryptroot) # default name to start
 
        until [[ $LUKS_PASS ]]; do
-               i=0
                tput cnorm
-               if [[ $op ]]; then
-                       dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" --separator $'\n' --title " $t " \
-                               --mixedform "\nEnter the password to decrypt $ROOT_PART\n\nThis is needed to create a keyfile." 0 0 0 \
-                               "Password:"  1 1 '' 1 11 "$COLUMNS" 0 1 \
-                               "Password2:" 2 1 '' 2 12 "$COLUMNS" 0 1 2>"$ANS" || return 1
-
-               else
-                       dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" --separator $'\n' --title " $t " --mixedform "$_luksomenu" 0 0 0 \
-                               "Name:"      1 1 "${LUKS_NAME:-cryptroot}" 1  7 "$COLUMNS" 0 0 \
-                               "Password:"  2 1 ''                        2 11 "$COLUMNS" 0 1 \
-                               "Password2:" 3 1 ''                        3 12 "$COLUMNS" 0 1 2>"$ANS" || return 1
+               dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" --separator $'\n' --title " $t " --mixedform "$_luksomenu" 0 0 0 \
+                       "Name:"      1 1 "${ans[0]}" 1  7 "$COLUMNS" 0 0 \
+                       "Password:"  2 1 ''          2 11 "$COLUMNS" 0 1 \
+                       "Password2:" 3 1 ''          3 12 "$COLUMNS" 0 1 2>"$ANS" || return 1
 
-               fi
+               mapfile -t ans <"$ANS"
 
-               while read -r line; do
-                       if [[ $op ]]; then
-                               case $i in
-                                       0) p="$line" ;;
-                                       1) p2="$line" ;;
-                               esac
-                       else
-                               case $i in
-                                       0) n="$line" ;;
-                                       1) p="$line" ;;
-                                       2) p2="$line" ;;
-                               esac
-                       fi
-                       (( i++ ))
-               done < "$ANS"
-
-               if [[ -z $op && -z $n ]]; then
+               if [[ -z "${ans[0]}" ]]; then
                        msg "Name Empty" "\nEncrypted device name cannot be empty.\n\nPlease try again.\n" 2
-               elif [[ -z $p || "$p" != "$p2" ]]; then
-                       [[ $op ]] || LUKS_NAME="$n"
+               elif [[ -z "${ans[1]}" || "${ans[1]}" != "${ans[2]}" ]]; then
+                       LUKS_NAME="${ans[0]}"
                        msg "Password Mismatch" "\nThe passwords entered do not match.\n\nPlease try again.\n" 2
                else
-                       [[ $op ]] || LUKS_NAME="$n"
-                       LUKS_PASS="$p"
+                       LUKS_NAME="${ans[0]}"
+                       LUKS_PASS="${ans[1]}"
                fi
        done
 
@@ -2151,7 +2018,7 @@ luks_pass()
 luks_show()
 {
        sleep 0.5
-       msg "$_luksnew" "\nEncrypted partition opened and ready for mounting.\n\n$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE "$LUKS_PART")\n\n"
+       msg "$_luksnew" "\nEncrypted partition ready for mounting.\n\n$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE "$LUKS_PART")\n\n"
 }
 
 luks_setup()
@@ -2184,22 +2051,6 @@ luks_basic()
        return 0
 }
 
-luks_keyfile()
-{
-       if [[ ! -e $MNT/crypto_keyfile.bin ]]; 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"
-               mkkey="$mkkey && chmod 000 /crypto_keyfile.bin"
-               mkkey="$mkkey && cryptsetup luksAddKey /dev/$n /crypto_keyfile.bin <<< '$LUKS_PASS'"
-               chrun "$mkkey"
-               sed -i 's/FILES=()/FILES=(\/crypto_keyfile.bin)/g' $MNT/etc/mkinitcpio.conf 2>$ERR
-       fi
-
-       return 0
-}
-
 luks_advanced()
 {
        if luks_setup; then
@@ -2218,7 +2069,9 @@ luks_advanced()
 }
 
 ###############################################################################
-# helper functions
+# simple functions
+# some help avoid repetition and improve usability of some commands
+# others are initial setup functions used before reaching the main loop
 
 ofn()
 {
@@ -2227,47 +2080,41 @@ ofn()
 
 die()
 {
-       local exitcode="$1"
+       # cleanup and exit the installer cleanly with exit code $1
+       local e="$1" # when e is 127 unmount /run/archiso/bootmnt and reboot
+
        trap - INT
-       trap - TSTP
        tput cnorm
-       if [[ -d $MNT ]] && command cd /; then
+       if [[ -d $MNT ]]; then
                umount_dir $MNT
-               if (( exitcode == 127 )); then
-                       umount -l /run/archiso/bootmnt
-                       sleep 0.5
-                       systemctl -i reboot
+               if (( e == 127 )); then
+                       umount_dir /run/archiso/bootmnt && sleep 0.5 && reboot -f
                fi
        fi
-
-       # restore custom linux console 0-15 colors when not rebooting
-       if [[ $TERM == 'linux' ]]; then
-               colors=("\e]P0191919" "\e]P1D15355" "\e]P2609960" "\e]P3FFCC66"
-               "\e]P4255A9B" "\e]P5AF86C8" "\e]P62EC8D3" "\e]P7949494" "\e]P8191919" "\e]P9D15355"
-               "\e]PA609960" "\e]PBFF9157" "\e]PC4E88CF" "\e]PDAF86C8" "\e]PE2ec8d3" "\e]PFE1E1E1")
-               printf "%b" "${colors[@]}" && clear && unset col
-       fi
-
-       exit "$exitcode"
+       exit $e
 }
 
 dlg()
 {
-       local var="$1" dialog_type="$2" title="$3" body="$4" n=0
-       shift 4
-       (( ($# / 2) > SHL )) && n=$SHL
-       
+       local var="$1"   # assign output from dialog to var
+       local dlg_t="$2" # dialog type (menu, check, input)
+       local title="$3" # dialog title
+       local body="$4"  # dialog message
+       local n=0        # number of items to display for menu and check dialogs
+
+       shift 4  # shift off args assigned above
+
+       # adjust n when passed a large list
+       local l=$((LINES - 20))
+       (( ($# / 2) > l )) && n=$l
+
        tput civis
-       case "$dialog_type" in
-               menu)
-                       dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --menu "$body" 0 0 $n "$@" 2>"$ANS" || return 1
-                       ;;
-               check)
-                       dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --checklist "$body" 0 0 $n "$@" 2>"$ANS" || return 1
-                       ;;
+       case "$dlg_t" in
+               menu) dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --menu "$body" 0 0 $n "$@" 2>"$ANS" || return 1 ;;
+               check) dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --checklist "$body" 0 0 $n "$@" 2>"$ANS" || return 1 ;;
                input)
                        tput cnorm
-                       local def="$1"
+                       local def="$1" # assign default value for input
                        shift
                        if [[ $1 == 'limit' ]]; then
                                dialog --backtitle "$DIST Installer - $SYS - v$VER" --max-input 63 --title " $title " --inputbox "$body" 0 0 "$def" 2>"$ANS" || return 1
@@ -2276,30 +2123,113 @@ dlg()
                        fi
                        ;;
        esac
+       # if answer file isn't empty read from it into $var
        [[ -s "$ANS" ]] && printf -v "$var" "%s" "$(< "$ANS")"
 }
 
 msg()
 {
-       local title="$1" body="$2"
+       # displays a message dialog
+       # when more than 2 args the message will disappear after sleep time ($3)
+       local title="$1"
+       local body="$2"
+       shift 2
        tput civis
-       if (( $# == 3 )); then
-               dialog --backtitle "$DIST Installer - $SYS - v$VER" --sleep "$3" --title " $title " --infobox "$body\n" 0 0
+       if (( $# )); then
+               dialog --backtitle "$DIST Installer - $SYS - v$VER" --sleep "$1" --title " $title " --infobox "$body\n" 0 0
        else
                dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --msgbox "$body\n" 0 0
        fi
 }
 
-json()
+live()
 {
-       curl -s "http://api.ipstack.com/$2" | python3 -c "import sys, json; print(json.load(sys.stdin)['$1'])"
+       local e=0
+
+       if (( $# == 0 )); then
+               msg "No Session" "\nRunning live requires a session to use.\n\nExiting..\n" 2
+               clear
+               die 1
+       elif ! select_keymap; then
+               clear
+               die 0
+       elif ! net_connect; then
+               msg "Not Connected" "\nRunning live requires an active internet connection.\n\nExiting..\n" 2
+               die 1
+       else
+               clear
+               pacman -Syyu archlinux-keyring --needed --noconfirm || die 1
+               pacman -S $AL_BASE_PKGS xorg-xinit xorg-server --needed --noconfirm || die 1
+               for ses; do
+                       case "$ses" in
+                               dwm)
+                                       pacman -S git --needed --noconfirm || die 1
+                                       mkdir -pv /root/suckless
+                                       for i in dwm dmenu st; do
+                                               git clone https://git.suckless.org/$i /root/suckless/$i && cd /root/suckless/$i && make PREFIX=/usr install
+                                       done
+                                       ;;
+                               i3-gaps|oepnbox|fluxbox|bspwm|awesome)
+                                       pacman -S "$ses" $WM_BASE_PKGS ${WM_EXT[$ses]} xterm --needed --noconfirm || die 1
+                                       ;;
+                               gnome|plasma|cinnamon|xfce4)
+                                       pacman -S "$ses" ${WM_EXT[$ses]} xterm --needed --noconfirm || die 1
+                                       ;;
+                               *) echo "error: invalid session for -l, --live, see -h, --help"; die 1 ;;
+                       esac
+               done
+               pacman -Scc --noconfirm
+               rm -rf "/var/cache/pacman/pkg/"*
+               cp -rfT /etc/skel /root || die 1
+               sed -i "/exec/ c exec ${WM_SESSIONS[$ses]}" /root/.xinitrc
+               printf "\n%s has been set as the login session in ~/.xinitrc, to start the session simply run\n\n\tstartx\n\n" "${WM_SESSIONS[$ses]}"
+               die 0
+       fi
+}
+
+usage()
+{
+       cat <<-EOF
+       usage: $1 [-hdl] [session]
+
+       options:
+           -h, --help     print this message and exit
+           -l, --live     install and setup a live session
+           -d, --debug    enable xtrace and log output to $DBG
+
+       sessions:
+           i3-gaps  - A fork of i3wm with more features including gaps
+           openbox  - A lightweight, powerful, and highly configurable stacking wm
+           dwm      - A dynamic WM for X that manages windows in tiled, floating, or monocle layouts
+           awesome  - A customized Awesome WM session created by @elanapan
+           bspwm    - A tiling wm that represents windows as the leaves of a binary tree
+           fluxbox  - A lightweight and highly-configurable window manager
+           gnome    - A desktop environment that aims to be simple and easy to use
+           cinnamon - A desktop environment combining traditional desktop with modern effects
+           plasma   - A kde software project currently comprising a full desktop environment
+           xfce4    - A lightweight and modular desktop environment based on gtk+2/3
+
+       distro name:
+
+           set the DIST environment variable before launching the installer eg.
+
+                   DIST='MyDistro' $1
+
+       editor used:
+
+           set the EDITOR environment variable before launching the installer eg.
+
+                   EDITOR='nano' $1
+
+       EOF
+       exit 0
 }
 
 yesno()
 {
        local title="$1" body="$2" yes='Yes' no='No'
-       (( $# >= 3 )) && local yes="$3"
-       (( $# >= 4 )) && local no="$4"
+       (( $# >= 3 )) && yes="$3"
+       (( $# >= 4 )) && no="$4"
        tput civis
        if (( $# == 5 )); then
                dialog --backtitle "$DIST Installer - $SYS - v$VER" --defaultno --title " $title " --yes-label "$yes" --no-label "$no" --yesno "$body\n" 0 0
@@ -2322,101 +2252,88 @@ debug()
        DEBUG=true
 }
 
-sigint()
+termcol()
 {
-       printf "\n^C caught, cleaning up...\n"
-       die 1
-}
+       local colors=(
+       "\e]P0191919" # #191919
+       "\e]P1D15355" # #D15355
+       "\e]P2609960" # #609960
+       "\e]P3FFCC66" # #FFCC66
+       "\e]P4255A9B" # #255A9B
+       "\e]P5AF86C8" # #AF86C8
+       "\e]P62EC8D3" # #2EC8D3
+       "\e]P7949494" # #949494
+       "\e]P8191919" # #191919
+       "\e]P9D15355" # #D15355
+       "\e]PA609960" # #609960
+       "\e]PBFF9157" # #FF9157
+       "\e]PC4E88CF" # #4E88CF
+       "\e]PDAF86C8" # #AF86C8
+       "\e]PE2ec8d3" # #2ec8d3
+       "\e]PFE1E1E1" # #E1E1E1
+       )
 
-print4()
-{
-       local str="$*"
-       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 }
-                       for (; i <= q * 2; i++) { p2 = p2 " " $i }
-                       for (; i <= q * 3; i++) { p3 = p3 " " $i }
-                       for (; i <= NF; i++) { p4 = p4 " " $i }
-                       printf "%s\n           %s\n           %s\n           %s", p1, p2, p3, p4
-               }' <<< "$str")"
-               printf "%s\n" "$str"
-       elif [[ $str ]]; then
-               printf "%s\n" "$str"
-       fi
+       [[ $TERM == 'linux' ]] && printf "%b" "${colors[@]}" && clear
 }
 
 errshow()
 {
-       exit_code="$?"
-       (( exit_code == 0 )) && return 0
+       [ $? -eq 0 ] && return 0
 
        local fatal=0 err=""
        err="$(sed 's/[^[:print:]]//g; s/\[[0-9\;:]*\?m//g; s/==> //g; s/] ERROR:/]\nERROR:/g' "$ERR")"
-       (( $1 == 1 )) && { fatal=1; shift; }
-       local txt="\nThe command exited abnormally:\n\n$1\n\n"
-
-       if [[ $err ]]; then
-               txt+="With the following message:\n\n$err\n\n"
-       else
-               txt+="With no error message:\n\n"
-       fi
+       [[ -z $err ]] && err="no error message was found"
 
-       if (( fatal == 1 )); then
-               txt+="Errors at this stage are fatal and the install cannot continue.\n"
-       else
-               txt+="Errors at this stage are non-fatal and can be either fixed or ignored depending on the error.\n"
-       fi
+       (( $1 == 1 )) && { fatal=1; shift; }
 
-       msg "Install Error" "$txt"
+       local txt="\nCommand: $1\n\n\n\nError: $err\n\n"
 
-       if (( fatal == 1 )); then
+       if (( fatal )); then
+               msg "Install Error" "${txt}Errors at this stage are fatal, the install cannot continue.\n"
                [[ -r $DBG && $TERM == 'linux' ]] && less "$DBG"
                die 1
        fi
 
+       msg "Install Error" "${txt}Errors at this stage are non-fatal and may be fixed or ignored depending on the error.\n"
        return 1
 }
 
-load_bcm()
-{
-       msg "Broadcom Wireless Setup" "\nDetected chipset is Broadcom BCM4352\n\nDisabling bcma/b43 modules and loading wl module.\n" 1
-       { rmmod wl; rmmod bcma; rmmod b43; rmmod ssb; modprobe wl; depmod -a; } >/dev/null 2>&1
-       BROADCOM_WL=true
-}
-
 prechecks()
 {
-       if [[ $1 -ge 0 ]] && ! grep -qw "$MNT" /proc/mounts; then
+       local i=1
+
+       if (( $1 >= 0 )) && ! grep -qw "$MNT" /proc/mounts; then
                msg "Not Mounted" "\nPartition(s) must be mounted first.\n" 2
-               SEL=4
-               return 1
+               SEL=4 i=0
        elif [[ $1 -ge 1 && -z $BOOTLDR ]]; then
                msg "No Bootloader" "\nBootloader must be selected first.\n" 2
-               SEL=5
-               return 1
+               SEL=5 i=0
        elif [[ $1 -ge 2 && (-z $NEWUSER || -z $USER_PASS) ]]; then
                msg "No User" "\nA user must be created first.\n" 2
-               SEL=6
-               return 1
+               SEL=6 i=0
        elif [[ $1 -ge 3 && -z $CONFIG_DONE ]]; then
                msg "Not Configured" "\nSystem configuration must be done first.\n" 2
-               SEL=7
-               return 1
+               SEL=7 i=0
        fi
-       return 0
+       (( i )) # return code
 }
 
 umount_dir()
 {
-       swapoff -a
-       [[ -d $1 ]] && umount -R "$1" >/dev/null 2>&1
-       return 0
+       mount | grep -q 'swap' && swapoff -a
+       for dir; do
+               if [[ -d $dir ]] && mount | grep -q "on $dir "; then
+                       if ! umount "$dir" 2>/dev/null; then
+                               sleep 0.5
+                               umount -f "$dir" 2>/dev/null || umount -l "$dir"
+                       fi
+               fi
+       done
 }
 
 chk_connect()
 {
-       msg "Network Connect" "\nVerifying network connection\n" 1
+       msg "Network Connect" "\nVerifying network connection\n" 0
        curl -sIN --connect-timeout 5 'https://www.archlinux.org/' | sed '1q' | grep -q '200'
 }
 
@@ -2424,19 +2341,31 @@ net_connect()
 {
        if chk_connect; then
                return 0
-       else
-               if hash nmtui >/dev/null 2>&1; then
-                       tput civis
-                       [[ $TERM == 'linux' ]] && printf "%b" "\e]P1191919" "\e]P4191919"
+       elif hash nmtui >/dev/null 2>&1; then
+               tput civis
+               if [[ $TERM == 'linux' ]]; then
+                       printf "%b" "\e]P1191919" "\e]P4191919"
                        nmtui-connect
-                       [[ $TERM == 'linux' ]] && printf "%b" "\e]P1D15355" "\e]P4255a9b"
-                       chk_connect
+                       printf "%b" "\e]P1D15355" "\e]P4255a9b"
                else
-                       return 1
+                       nmtui-connect
                fi
+               chk_connect
+       elif hash wifi-menu >dev/null 2>&1; then
+               wifi-menu
+               chk_connect
+       else
+               return 1
        fi
 }
 
+no_bg_install()
+{
+       [[ $BG_PID ]] || return 0
+       msg "Install Running" "\nA background install process is currently running.\n" 2
+       return 1
+}
+
 system_devices()
 {
        IGNORE_DEV="$(lsblk -lno NAME,MOUNTPOINT | awk '/\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')"
@@ -2462,8 +2391,9 @@ system_identify()
 {
        if [[ $VM ]]; then
                UCODE=''
-       elif grep -q 'AuthenticAMD' /proc/cpuinfo; then
-               UCODE="amd-ucode"
+       # amd-ucode is not needed it's provided by linux-firmware
+       # elif grep -q 'AuthenticAMD' /proc/cpuinfo; then
+       #       UCODE="amd-ucode"
        elif grep -q 'GenuineIntel' /proc/cpuinfo; then
                UCODE="intel-ucode"
        fi
@@ -2483,47 +2413,44 @@ system_identify()
        _prep+="\n  - Basic system configuration, kernel, shell, login, packages, etc..\n\nOnce you're happy with the choices and the required steps are complete, the main install can be started."
 }
 
-check_background_install()
-{
-       [[ $RSYNC_PID || $MIRROR_PID ]] || return 0
-       msg "Install Running" "\nA background install process is currently running.\n" 2
-       return 1
-}
-
 ###############################################################################
 # entry point
 
+# enable some nicer colours in the linux console
+termcol
+
 if (( UID != 0 )); then
        msg "Not Root" "\nThis installer must be run as root or using sudo.\n\nExiting..\n" 2
        die 1
 elif ! grep -qwm 1 'lm' /proc/cpuinfo; then
        msg "Not x86_64 Architecture" "\nThis installer only supports x86_64 architectures.\n\nExiting..\n" 2
        die 1
-elif [[ $1 =~ (-d|--debug) ]]; then
-       debug
+else
+       case "$1" in
+               -d|--debug) debug ;;
+               -h|--help) usage "$0" ;;
+               -l|--live) shift; live "$@" ;;
+       esac
 fi
 
 # trap ^C to perform cleanup
-trap sigint INT
+trap 'printf "\n^C\n" && die 1' INT
 
 system_identify
 system_devices
 
-msg "Welcome to the $DIST Installer" "\nThis will help you get $DIST setup on your system.\nHaving previous GNU/Linux and shell experience will be an asset, however we try our best to keep things simple.\n\nIf you are unsure about an option, a default will be listed or\nthe first selected option will usually be the default (excluding language and timezone).\n\n\nMenu Navigation:\n\n - Select items with the arrow keys or the option number.\n - Use [Space] to toggle options and [Enter] to confirm.\n - Switch between buttons using [Tab] or the arrow keys.\n - Use [Page Up] and [Page Down] to jump whole pages\n - Press the highlighted key of an option to select it.\n"
-
-select_keymap || { clear; die 0; }
-
-if lspci -vnn -d 14e4: | grep -q 'BCM4352'; then
-       load_bcm
-fi
+msg "Welcome to the $DIST Installer" "$_welcome"
 
-if ! net_connect; then
+if ! select_keymap; then
+       clear; die 0
+elif ! net_connect; then
        msg "Not Connected" "\nThis installer requires an active internet connection.\n\nExiting..\n" 2
        die 1
 fi
 
-while true; do
-       select_main
-done
+FORMATTED=""
 
+while :; do
+       main
+done
 # vim:fdm=marker:fmr={,}