#! /bin/sh -
#
# The installer of Dragora GNU/Linux-Libre
#
# Copyright (c) 2019-2022 Matias Fonzo, <selk@dragora.org>.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Exit immediately on any error
set -e

PROGRAM="${0##*/}"
TMPDIR="${TMPDIR:-$HOME}"
TMPFILE="${TMPDIR}/${PROGRAM}.${RANDOM-0}$$"
LOCKFILE=/tmp/dragora-installer.lockfile

# Override locale settings
LANG=C
LC_ALL=C
export LANG LC_ALL

unmountFilesystems()
{
    for filesystem in \
     /media/dragora-root/sys   \
     /media/dragora-root/proc  \
     /media/dragora-root/dev   \
     /media/dragora-root       \
     /media/dragora-packages ; \
    do
        if mountpoint -q "$filesystem"
        then
            echo ""
            echo ""
            echo "Unmounting $(findmnt -n -o SOURCE $filesystem) from $filesystem ..."
            if ! umount -v -R "$filesystem"
            then
                echo "    ^ Doing a lazy unmount for \`${filesystem}' ..."
                umount -v -l "$filesystem"
            fi
        fi
    done
    unset -v filesystem
}

chkstatus_or_exit()
{
    status=$?

    # Clean up temporary files
    rm -f -- "$TMPFILE" "$LOCKFILE"

    # Clean up temporary subdirectory if 'PRESERVE' is unset or null
    test -z "$PRESERVE" && rm -rf -- "$SUBTMPDIR"

    # Unmount possible (previously) mounted file systems
    unmountFilesystems

    if test $status -ne 0
    then
        printf '%s\n' "" "^ Return status = $status" 1>&2
        exit 2;
    fi

    unset -v status
}

# Sanity checks

if test ! -d "$TMPDIR"
then
    echo "${PROGRAM}: \`${TMPDIR}' is not a qualified temporary directory" 1>&2
    exit 1;
fi
if test ! -w "$TMPDIR"
then
    echo "${PROGRAM}: \`${TMPDIR}' is not a writable temporary directory" 1>&2
    exit 1;
fi

trap 'chkstatus_or_exit' EXIT HUP INT QUIT ABRT TERM

umask 077;	# Remove access for all but user.

# Set a lock to allow only one instance of the installer

if ( set -C ; echo ": $PROGRAM - locked" > $LOCKFILE ) 2> /dev/null
then
    true
else
    if test -e "$LOCKFILE"
    then
        echo "Only one instance of \`${PROGRAM}' is allowed." 1>&2
        exit 1;
    else
        echo "${PROGRAM}: \`${LOCKFILE}' lock failed." 1>&2
        exit 2;
    fi
fi

# Remove write permission for group and other
umask 022

# Create subdirectory to store the files produced by the installer

# Default sets to "${HOME}/.dragora-installer"
SUBTMPDIR="${TMPDIR}/.${PROGRAM}"
mkdir -p -- "$SUBTMPDIR"
chmod 700 -- "$SUBTMPDIR"

# Detect and prepare initial list of Linux partition(s)

if fdisk -l | sed -e 's|Linux filesystem|Linux|g' | grep -E -q -m 1 'Linux$'
then
    fdisk -l | sed -e 's|Linux filesystem|Linux|g' | grep -E 'Linux$' | \
     sort > "${SUBTMPDIR}/partitions"
else
    cat 1>&2 << EOF
Linux partitions were not detected.

A Linux partition is required to continue the installation.  You can
use utilities such as fdisk(8), cfdisk(8) or parted(8) to create at
least one Linux partition.  Then run \`${PROGRAM}' again.
EOF
    exit 1;
fi

# Determine the maximum size of the terminal to be used on the dialogues

echo "Checking terminal size ..."
LINES="${LINES:-$(tput lines)}"
COLUMNS="${COLUMNS:-$(tput cols)}"

export SUBTMPDIR LINES COLUMNS

dialog --colors \
 --backtitle "\\ZbThe installer of Dragora GNU/Linux-Libre 3.0" \
 --title "INSTALLER INFORMATION" \
 --cr-wrap --msgbox \
"Welcome to \\Z3${PROGRAM}\\Zn.

    This program will help you install Dragora 3.0 on your computer.

Use the cursor keys to move around in the installer's menus.

Press \\Z3[Tab]\\Zn to jump to the next option and \
\\Z3[Shift]\\Zn\\Zb\\Z7+\\Zn\\Z3[Tab]\\Zn to jump to the previous one.

Use \\Z3[Space]\\Zn to select or unselect an item, \\Z3[Enter]\\Zn to \
confirm or proceed to the next menu.

You can use \\Z3[Ctrl]\\Zn\\Zb\\Z7+\\Zn\\Z3[C]\\Zn to abort the \
installation at any time.

To quit a dialog (such as the one you are in), press \\Z3[Esc]\\Zn.

" $((LINES - 4)) $((COLUMNS - 8))

# Try to detect and mount the hybrid ISO image, there may be a USB memory
# stick already inserted.  If not, the media menu will be displayed.

mkdir -p -- /media/dragora-packages

if ! blkid -t LABEL="Dragora Packages" > /dev/null
then
    dialog --colors \
     --backtitle "\\ZbInstallation Medium" \
     --title "Pendrive/SDCard/CDROM" \
     --cr-wrap --msgbox \
"
Please insert the medium labeled \"Dragora Packages\" and
press \\Z3[Enter]\\Zn to continue.  Otherwise, a media selection
menu will be displayed.
" 9 60
    if blkid -t LABEL="Dragora Packages" > /dev/null
    then
        if ! mountpoint -q /media/dragora-packages
        then
            mount -v -t iso9660 LABEL="Dragora Packages" \
             /media/dragora-packages
            echo '/media/dragora-packages/packages' \
             > "${SUBTMPDIR}/MediumFound"
            sleep 1
        fi
    else
        . @PARTS@MenuMedia
    fi
else
    if ! mountpoint -q /media/dragora-packages
    then
        mount -v -t iso9660 LABEL="Dragora Packages" /media/dragora-packages
        sleep 2
    fi
    echo '/media/dragora-packages/packages' > "${SUBTMPDIR}/MediumFound"
fi

# Attempt to unmount possible pre-mounted filesystem(s)
mountpoint -q /media/dragora-root/sys && umount /media/dragora-root/sys
mountpoint -q /media/dragora-root/proc && umount /media/dragora-root/proc
mountpoint -q /media/dragora-root/dev && umount /media/dragora-root/dev

# Clean up possible empty mount-directories
rmdir -- /media/dragora-packages /media/dragora-root 2> /dev/null || true

# Double-check to see the installation directory
if test ! -f "${SUBTMPDIR}/MediumFound"
then
   dialog --colors \
     --backtitle "\\ZbInstallation Medium" \
     --title "MEDIUM NOT FOUND" \
     --sleep 7 --cr-wrap --infobox \
"
No means of installation was found to proceed
with the installation of Dragora.

Please check your drives and the directory
containing the software packages...
" 9 49
    exit 99;
fi

. @PARTS@MakeSwap;		# Swap devices.
. @PARTS@MakeFS;		# Linux partitions.
. @PARTS@FstabEdit;		# File system table edition (fstab).
. @PARTS@MountRoot;		# Mount root partition for installation.
. @PARTS@FstabMounts;		# Mount rest of file systems from fstab.
. @PARTS@ShowSeries;		# Software series.
. @PARTS@InstallPackages;	# Package installation.
. @PARTS@PostInstall;		# Post-installation.
. @PARTS@SetPassword;		# Password for root.
. @PARTS@MenuBootloader;	# Boot loader installation.
. @PARTS@ConfServices;		# Running services.

if test -e /media/dragora-root/etc/fstab
then
    if mountpoint -q /media/dragora-packages
    then
        umount /media/dragora-packages
    fi
    if test -s "${SUBTMPDIR}/SeTCDdev"
    then
        _status=0
        dialog --clear --colors \
         --title "The Setup for Dragora has been completed" \
         --cr-wrap --msgbox \
"
If you are ready, press \\Z3[Enter]\\Zn to eject
the installation disc...
" 8 0 || _status=$?

        if test $_status -eq 0
        then
            cdrom_device="$(cat -- "${SUBTMPDIR}/CDDevice")"

            # Try to eject using SCSI commands, fallback on CDROM eject command
            eject --scsi "$cdrom_device" || eject --cdrom "$cdrom_device"

            dialog \
             --title "The Setup for Dragora has been completed" \
             --msgbox "\\nPlease remove the installation disc.\\n" 7 44 || true

            # Attempt to use the tray close command
            eject -t "$cdrom_device" > /dev/null 2>&1 || true
        fi
        unset -v _status cdrom_device
    fi
fi

sync

_status=0
dialog --clear --colors \
 --backtitle "\\ZbSystem restart" \
 --title "The Setup for Dragora has been completed." \
 --cr-wrap --yesno \
"
Would you like to reboot the system now?
" 7 44 || _status=$?
case $_status in
0)
    unset -v _status
    dialog --clear
    unmountFilesystems
    exec reboot -d -f
    ;;
*)
    unset -v _status
    unmountFilesystems
    echo ""
    echo ""
    echo ""
    echo "Going out to the shell..."
    echo ""
    echo ""
    exit 0
    ;;
esac

