#!/bin/bash
rm -f /tmp/disk*
rm -f /tmp/device
rm -f /tmp/file*
rm -f /tmp/cpar*
rm -f /tmp/part*

lang=$(echo $LANG | awk -F\_ '{print $1}')

case $lang in
    DE|de*)
        export title1="Laufwerke"
        export title2="TUXEDO chroot helper"
        export title3="Reparatur Option waehlen"
        export text1="Sorry, keine Platte ausgewaehlt, beende."
        export text2="Gewaehlte Disk:"
        export text3="Aufgeschlossen"
        export text4="Betrete installiertes System"
        export text5="Verlassen Sie das Chroot mittels 'exit' oder Ctrl+d"
        export text6="Nicht verschluesselt"
        export text7="Waehlen Sie die Festplatte, welche untersucht werden soll."
        export text8="Kein TUXEDO OS gefunden, automatische Reparatur nicht moeglich. Beende."
        export text9="Mehrere Linux Installationen gefunden\n\nWaehlen Sie eine Partition fuer chroot"
        export text10="Sorry, keine Partition ausgewaehlt, beende."
        export text11="Moechten Sie den Versuch einer automatischen Reparatur starten? Es wird versucht, das System auf die TUXEDO Standard Einstellungen zurueckzusetzen. Es werden im Vorfeld einige Abfragen erscheinen."
        export text12="Kein Passwort eingegebn."
        export text20="Kein System gefunden, ebenuell eine Datenpartition. Erneut versuchen?"
        export text21="Falsches Passwort. Erneut versuchen?"
        export text22="Gewaehlte Partition:"
	export text23="Kein TUXEDO OS, wollen Sie per chroot in Ihre Installation wechseln?"
	export text24=" Druecken Sie Enter zum Neustart."
        export textcr="LUKS Verschluesselungspasswort eingeben"
        export textrep="Bitte waehlen Sie die Art der Reparatur.\n\nAlle Aktionen werden in Ihrem installierten System als Root ausgefuehrt und sind in der Lage, das System potentiell zu zerstoeren! Wenn Sie sich nicht sicher sind, waehlen Sie Abbrechen.\n"
        export textres="Beim Zuruecksetzen auf Werkseinstellungen werden \Z1\Zballe 32Bit Pakete, sowie alle Fremdpakete entfernt\Z0\ZB. Nachinstallierte Anwendungen werden moeglicherweise entfernt. Es werden keine Daten in Ihrem Home geloescht.\n\nDie Paketquellen werden auf Standardquellen geaendert. Wenn Sie hier auf Nein klicken, wird das Script beendet, ohne etwas an ihrem installierten System zu aendern und ein Reboot ausgefuehrt."
        export textrep2="Kein Tuxedo OS gefunden, Sie haben die folgende Moeglichkeiten, an ihrem installierten System zu arbeiten:"
        export menu1="Ausfuehren von Tuxedo-Tomte"
        export menu2="Zuruecksetzen auf Werkseinstellungen"
        export menu3="Grub reinstallieren"
        export menu4="Initial Ramdisk neu erstellen mit starker Kompression"
        export menu5="Mittels chroot das installierte System betreten."
        export menu6="Nvidia Treiber neu installieren"
        export menu7="Alle Kernel loeschen und den aktuellen Tuxedo Kernel installieren"
        export tomtetext="Es wird nun versucht, ein tomte reconfigure all in Ihrem installierten System auszufuehren.\nSie koennen an dieser Stelle noch unterbrechen, indem Sie hier auf Abbrechen klicken. Das Script wird dann beendet, ohne etwas an ihrem installierten System zu machen."
	export ja="Ja"
	export nein="Nein"
	export canc="Abbrechen"
        ;;
    *)
        export title1="Devices"
        export title2="Automated Repair Trial with tuxedo-tomte"
        export title3="Choose repair option"
        export text1="Sorry, no disk choosen, exiting."
        export text2="Choosen disc:"
        export text3="Decrypted"
        export text4="Enter installed system"
        export text5="Exit the chroot using 'exit' or Ctrl+d"
        export text6="Not crypted"
        export text7="Select the hard disk to be examined."
        export text8="No TUXEDO OS found, atumatic repair tasks possible. Exiting."
        export text9="Multiple linux installations found.\n\nChoose one partition for chroot"
        export text10="Sorry, no partition choosen, exiting."
        export text11="Would you like to attempt an automatic repair? An attempt will be made to reset the system to the TUXEDO default settings. A few queries will appear in advance."
        export text12="No password given."
        export text20="No system found, maybe a data partition. Try again?"
        export text21="Wrong password. Try again?"
        export text22="Choosen partition:"
	export text23="No TUXEDO OS, want to chroot into your installation?"
	export text24=" Press Enter to reboot"
        export textcr="input LUKS passphrase"
        export textrep="Please select the type of repair.\n\nAll actions will be executed in your installed system as root and are capable of potentially destroying the system! If you are not sure, select Cancel.\n"
        export textrep2="No Tuxedo OS found, you have the following options to work on your installed system:"
        export textres="When resetting to factory settings, \Z1\Zball 32-bit packages and all third-party packages will be removed\Z0\ZB. Subsequent applications may be removed. No data in your home will be deleted.\n\nPackage sources will be restored to default sources. If you click No here, the script will exit without changing anything on your installed system and reboot."
        export menu1="Run Tuxedo-Tomte"
        export menu2="Factory reset"
        export menu3="Reinstall Grub"
        export menu4="Initial Ramdisk rebuild with strong compression"
        export menu5="Enter the installed system using chroot"
        export menu6="Reinstall Nvidia Driver"
        export menu7="Remove all Kernels and reinstall recent Tuxedo Kernel"
        export tomtetext="An attempt is now being made to execute a tomte reconfigure all in your installed system.\nYou can still interrupt this process by clicking Cancel at this point. The script will then be terminated without making any changes to your installed system."
	export ja="Yes"
	export nein"No"
	export canc="Cancel"
        ;;
esac
rm -f /tmp/disk*
rm -f /tmp/devic*
rm -f /tmp/cpa*
rm -f /tmp/sysp*


is_system() {
    is_system=""
    if [ $(ls -f /mnt/$syspart/etc/fstab 2>/dev/null) ] || [ $(ls -f /mnt/$syspart/@/etc/fstab 2>/dev/null) ]; then
        is_system="system"
    fi
}

is_deb() {
    is_deb=""
    if [ -e /mnt/$syspart/usr/bin/dpkg ] || [ -e /mnt/$syspart/@/usr/bin/dpkg ]; then
	is_deb="deb"
    fi
}

find_crypt() {
    is_crypt=$(lsblk -fs | grep $part | grep -i luks | awk '{print $1}')
    if [ "$is_crypt" ]; then
        is_luks1=$(cryptsetup luksDump /dev/$part | grep Version | awk '{print $2}' | grep 1)
        is_luks2=$(cryptsetup luksDump /dev/$part | grep Version | awk '{print $2}' | grep 2)
    fi
}

find_disk() {
    rm -f /tmp/disk* 2> /dev/null
    rm -f /tmp/device* 2> /dev/null
    lsblk | awk '/disk/{ print $1 }' | sort >/tmp/disklist2
    for m in $(lsblk -lf -o Name,TYPE,FSTYPE | grep -E "ext|btrfs|xfs|LUKS" | awk '{ print $1 }' | egrep "sd|hd|vd" | cut -c1-3 | sort | uniq); do sed -i "/\<$m\>/d" /tmp/disklist2; done
    for n in $(lsblk -lf -o Name,TYPE,FSTYPE | grep -E "ext|btrfs|xfs|LUKS" | awk '{ print $1 }' | grep nvme | cut -c1-7 | sort | uniq); do sed -i "/\<$n\>/d" /tmp/disklist2; done
    for e in $(lsblk -lf -o Name,TYPE,SUBSYSTEMS | grep usb | awk '/disk/{ print $1 }'| sort | uniq); do sed -i "/\<$e\>/d" /tmp/disklist2; done
    blacklist=$(cat /tmp/disklist2)
    for x in $(lsblk -dnl -o NAME,RM | grep -E -v " 1|loop" | awk '{print $1}'); do lsblk -lfo NAME,FSTYPE | grep $x > /tmp/disk_$x.txt; done
    for liste in /tmp/disk_*; do cat $liste >> /tmp/disklist.txt; done
    if [ $blacklist ]; then
        for i in $(lsblk -dn -o NAME,TYPE,SUBSYSTEMS | grep -E -iv "loop|rom|usb|$blacklist" | awk '{print$1}'); do
        z=$(lsblk -dn -o NAME,Size | grep $i | awk '{print $2}')
        echo -e  \"$z'\t'$i\" \"'   \t'$(cat /sys/block/$i/device/model | sed 's/*_//')\"
        done 1> /tmp/device1 2> /dev/null
    else
        for i in $(lsblk -dn -o NAME,TYPE,SUBSYSTEMS | grep -E -iv "loop|rom|usb" | awk '{print$1}'); do
            z=$(lsblk -dn -o NAME,Size | grep $i | awk '{print $2}')
            echo -e  \"$z'\t'$i\" \"'   \t'$(cat /sys/block/$i/device/model | sed 's/*_//')\"
        done 1> /tmp/device1 2> /dev/null
    fi
    cat /tmp/device1 | sort 1> /tmp/device 2> /dev/null
    if [ "$(cat /tmp/device | wc -l)" -ge 2 ]; then
        disk=$(dialog --colors --cancel-label "$canc" --title "\Z1$title2" --menu "\n$text7\n\n" 10 63 0 --file "/tmp/device" 3>&1 1>&2 2>&3 3>&- | awk '{print$2}')
	clear
    else
        disk=$(cat /tmp/device | awk '{print $2}' | sed 's/\"//')
    fi
    if [ -z "$disk" ]; then
        dialog --msgbox "$text1" 8 50 3>&1 1>&2 2>&3 3>&-
	clear
        do_cancel
    fi
    echo $text2 $disk
}

partlist() {
    blkid -c /dev/null | grep -iE "ext|btrf|xfs|luks" | grep -E -iv "ntfs|gap|ventoy|reserved|fat" | awk '{print $1}' | grep $disk | awk -F\: '{print $1}' | awk -F\/ '{print $3}' | sort > /tmp/partlist1
    for x in $(cat /tmp/partlist1); do
    mkdir -p /mnt/$x && mount /dev/$x /mnt/$x 2>/dev/null
    done
    is_boot=$(ls -d /mnt/*/grub 2>/dev/null | awk -F\/ '{print $3}' 2>/dev/null || ls -d /mnt/*/@/grub 2>/dev/null | awk -F\/ '{print $3}' 2>/dev/null)
    if [ "$is_boot" ]; then
    for p in $(cat /tmp/partlist1 | grep -v $is_boot); do
        x=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $1}')
        z=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $2}')
        y=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $3}')
	echo -e  $p \"'     '$z'     '$y\"
    done 1> /tmp/partlist 2> /dev/null
    umount -R /mnt/* 2>/dev/null
    else
    for p in $(cat /tmp/partlist1); do
        x=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $1}')
        z=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $2}')
        y=$(lsblk -lf -o NAME,FSTYPE,SIZE | grep $p | sed s/crypto_// | awk '{print $3}')
	echo -e  $p \"'     '$z'     '$y\"
    done 1> /tmp/partlist 2> /dev/null
    umount -R /mnt/* 2>/dev/null
    fi
    if [ "$(cat /tmp/partlist | wc -l)" -ge 2 ]; then
        part=$(dialog --colors --cancel-label "$canc" --title "\Z1$title2" --menu "\n$text9\n\n" 10 63 0 --file "/tmp/partlist" 3>&1 1>&2 2>&3 3>&-)
        if [ -z "$part" ]; then
	    dialog --msgbox "$text10" 8 30 3>&1 1>&2 2>&3 3>&-
	    clear
    	    do_cancel
	fi
    else
        part=$(cat /tmp/partlist | awk '{print $1}')
    fi
}

find_part() {
        syspart=$part
        mkdir /mnt/$syspart 2>/dev/null
        mount /dev/$syspart /mnt/$syspart
        syspart=$part
        is_system 2>/dev/null
        if [ $(ls -ld /mnt/$syspart/@ 2>/dev/null | awk '{print $2}') ]; then
            svol=1
        else
            svol=0
        fi
        if [ -z "$is_system" ]; then
            umount /mnt/$syspart 2>/dev/null
            dialog --yes-label "$ja" --no-label "$nein" --yesno "$text20" 10 60 3>&1 1>&2 2>&3 3>&-
	    clear
            if [ "$?" = 0 ]; then
                find_disk
                partlist
                find_part
            else
                do_cancel
            fi
        else
	    is_deb 2>/dev/null
	    find_nvidia 2>/dev/null
        fi
        umount -R /mnt/* 2>/dev/null
        umount -R /mnt 2> /dev/null
}

find_crpart2() {
        pwdata=$(tempfile 2>/dev/null)
        trap "rm -f $pwata" 0 1 2 5 15
        cpart=$part
        ERC=1
        until [ $ERC -ne 1 ]
            do
            trap "rm -f $pwata" 0 1 2 5 15
            dialog --title "LUKS password" --cancel-label "$canc" --clear --insecure --passwordbox "$textcr" 10 40 2> $pwdata >&1 >/dev/tty
	    clear
            ret=$?
            if [ "$ret" = 0 ] && [ $(cat $pwdata) ]; then
                printf '%s\n' $(cat $pwdata) | cryptsetup luksOpen -q /dev/$cpart cryptdev_$cpart
                ret1=$?
            else
                ret1=255
            fi
            if [ "$ret" = 0 ] && [ "$ret1" -ge 1 ] && [ ! $(cat $pwdata) ]; then
                clear
                sleep 1
                ERC=1
            else
                if [ "$ret" = 0 ] && [ "$ret1" -ge 1 ]; then
                    dialog --msgbox "$text21" 8 30 3>&1 1>&2 2>&3 3>&-
		    clear
                    ERC=1
                else
                    set +H
                    ERC=0
                    break;
                fi
            fi
        done
        case $ret in
            0)
                echo ""
                ;;
            1)
                do_cancel
                ;;
            255)
                do_cancel
                ;;
        esac
        for z in $( vgscan | awk -F\" '{ print $2 }'); do vgchange -ay $z >/dev/null; done 2>/dev/null
        spart=$(blkid -c /dev/null | grep mapper | grep -Evi "ventoy|live" | grep -E "ext|btrfs|xfs" | awk '{print $1}' | awk -F\: '{print $1}')
        syspart=$cpart
        mkdir -p /mnt/$syspart
        mount $spart /mnt/$syspart
        if [ $(ls -ld /mnt/$syspart/@ 2>/dev/null | awk '{print $2}') ]; then
            svol=1
            cdev=$(awk '/luks/{print $1}' /mnt/$syspart/@/etc/crypttab)
        else
            svol=0
            cdev=$(awk '/luks/{print $1}' /mnt/$syspart/etc/crypttab)
        fi
		is_deb 2>/dev/null
        umount -R /mnt/* 2>/dev/null
        umount -R /mnt 2>/dev/null
        for z in $( vgscan | awk -F\" '{ print $2 }'); do vgchange -a n $z >/dev/null; done >/dev/null
        for c in $( dmsetup info -c | awk '/LUKS/{ print $1 }'); do cryptsetup luksClose $c >/dev/null; done >/dev/null
        printf '%s\n' $(cat $pwdata) | cryptsetup luksOpen -q /dev/$cpart $cdev
        for z in $( vgscan | awk -F\" '{ print $2 }'); do vgchange -ay $z >/dev/null; done >/dev/null
        syspart=$(blkid | grep mapper | grep -E "ext|btrf|xfs" | grep -Evi "ventoy|live" | awk '{print $1}' | awk -F\: '{print $1}')
}

find_crpart1() {
        pwdata=$(tempfile 2>/dev/null)
        trap "rm -f $pwata" 0 1 2 5 15
        cpart=$part
        syspart=luks\-$(lsblk -fl | grep $part | awk '/LUKS/{print $4}')
        # get password
        ERC=1
        until [ $ERC -ne 1 ]
            do
            trap "rm -f $pwata" 0 1 2 5 15
            dialog --title "LUKS 1 password" --cancel-label "$canc" --clear --insecure --passwordbox "$textcr" 10 40 2> $pwdata >&1 >/dev/tty
	    clear
            ret=$?
            if [ "$ret" = 0 ] && [ "$(cat $pwdata)" ]; then
                printf '%s\n' ${CPASS} | cryptsetup luksOpen -q /dev/$cpart $syspart 2>/dev/null
                ret1=$?
            else
                ret1=255
            fi
            if [ "$ret" = 0 ] && [ "$ret1" -ge 1 ] && [ ! "$(cat $pwdata)" ]; then
                sleep 1
                ERC=1
            else
                if [ "$ret" = 0 ] && [ "$ret1" -ge 1 ]; then
                    dialog --msgbox "$text21" 3>&1 1>&2 2>&3 3>&-
		    clear
                    ERC=1
                else
                    set +H
                    ERC=0
                    break;
                fi
            fi
        done
        case $ret in
            0)
                ;;
            1)
                #dialog --msgbox "Cancel Pressed" 8 30
                echo "Cancel pressed."
                do_cancel
                ;;
            255)
                do_cancel
                ;;
        esac
        mkdir /mnt/$syspart
        mount /dev/mapper/$syspart /mnt/syspart
		is_deb 2>/dev/null
        if [ $(ls -ld /mnt/@ 2>/dev/null | awk '{print $2}') ]; then
            svol=1
            umount -R /mnt 2> /dev/null
            umount -R /mnt/* 2> /dev/null
        else
            svol=0
            umount -R /mnt 2> /dev/null
            umount -R /mnt/* 2> /dev/null
        fi
}

do_work() {
    if [ "$is_luks2" ]; then
        if [ "$svol" = 1 ]; then
            mount -o subvol=@ $syspart /mnt
        else
            mount $syspart /mnt
        fi
    fi
    if [ "$is_luks1" ]; then
        if [ "$svol" = 1 ]; then
            mount -o subvol=@ /dev/mapper/$syspart /mnt
        else
            mount /dev/mapper/$syspart /mnt
        fi
    fi
    if [ ! "$is_crypt" ]; then
        if [ "$svol" = 1 ]; then
            mount -o subvol=@ /dev/$syspart /mnt
        else
            mount /dev/$syspart /mnt
        fi
    fi
    for i in /dev /dev/pts /proc /sys /sys/firmware/efi/efivars /run; do  mount -B $i /mnt$i; done
    mv /mnt/etc/resolv.conf /mnt/etc/resolv.conf.bak 2>/dev/null
    cp -a /etc/resolv.conf /mnt/etc/resolv.conf
    hostname chroot-helper
	echo "chroot task"
	echo "using chroot to enter installed system"
	echo "use 'ctrl + d' or type exit and [enter] to leave the chroot"
	echo ""
	if [ "$lang" = DE ]; then
	    chroot $target/mnt /bin/sh -c "mount -a || true && loadkeys de && /bin/bash"
	else
	    chroot $target/mnt /bin/sh -c "mount -a || true && /bin/bash"
	fi
    hostname siduction
    rm -f /mnt/etc/resolv.conf
    mv /mnt/etc/resolv.conf.bak /mnt/etc/resolv.conf 2>/dev/null
    umount -R /mnt/* 2> /dev/null
    umount -R /mnt 2> /dev/null
}

do_cancel() {
    umount -R /mnt/* 2>/dev/null
    umount -R /mnt 2>/dev/null
    umount -R /mnt/* 2>/dev/null
    umount -R /mnt 2>/dev/null
    for z in $( vgscan | awk -F\" '{ print $2 }'); do vgchange -a n $z >/dev/null; done
    for c in $( dmsetup info -c | awk '/LUKS/{ print $1 }'); do cryptsetup luksClose $c >/dev/null; done
    touch /tmp/cancel
    exit 0
}

find_disk
partlist
find_crypt
if [ "$is_luks2" ]; then
	find_crpart2
fi
if [ $is_luks1 ]; then
	find_crpart1
fi
if [ ! $is_crypt ]; then
	find_part
fi
do_work

umount -R /mnt/* 2>/dev/null
umount -R /mnt 2>/dev/null

for z in $( vgscan | awk -F\" '{ print $2 }'); do vgchange -a n $z >/dev/null; done
for c in $( dmsetup info -c | awk '/LUKS/{ print $1 }'); do cryptsetup luksClose $c >/dev/null; done

exit 0

