#!/bin/bash
# Gettext internationalization
#
# Copyright 2022-2024 Dimitris Tzemos, GR
#!/bin/bash
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
###################################################################
####             install-upgrade-kernel-ext-usb                ####
###################################################################
# script to install/upgrade new kernel images on slackel          #
# on slackel installed in external usb or ssd disk                #
# when kernel upgrade on repos                                    #
# when installing/upgrading kernel an initrd is created           #
# so slackel can boot from external usb or ssd disk               #
# This script created for slackel/salix                           #
#                                                                 #
###################################################################

AUTHOR='Dimitris Tzemos - dijemos@gmail.com'
LICENCE='GPL v3+'
SCRIPT=$(basename "$0")
SCRIPT=$(readlink -f "$SCRIPT")
VER=5.0

init(){

		if [ "$UID" != "0" ]; then
			echo "You need to be root to run this"
			exit 1
		fi

        # Translations only work with utf8 locales
        if [ ! `echo $LANG | grep -i utf` ]; then
			LANG=C
        fi

        # Gettext internationalization
        export TEXTDOMAIN="install-upgrade-kernel-ext-usb"
        export TEXTDOMAINDIR="/usr/share/locale"
        . gettext.sh

        # Path needs to be extended in case you're only half a root :)
        export PATH="/usr/sbin:/sbin:${PATH}"
}

usage(){
        echo "`eval_gettext 'USAGE: install-upgrade-kernel-ext-usb [install|upgrade] [generic] [10] [ext4]'`"
        echo
        echo "`eval_gettext '   OPTIONS:'`"
        echo "`eval_gettext '   install     Install generic kernel'`"
        echo "`eval_gettext '   upgrade     Upgrade generic kernel removing the old one'`"
        echo "`eval_gettext '   generic     Download generic kernel and also create an initrd'`"
        echo "`eval_gettext '   10       Time in seconds to wait for usb to add to the initrd'`"
        echo "`eval_gettext '   ext4      Filesystem of installed system, default ext4'`"
        exit 1
}

# Check which options are used from the command line
checkoptions(){
ROOTPART=$(lsblk -l -o name,mountpoint| grep /$|sed "s,\([^[:space:]]*\).*,/dev/\1,")
ROOTNAME=$(echo $ROOTPART|sed "s,/dev/,,")
ROOTUUID=$(lsblk -l -o name,uuid|grep ^$ROOTNAME|sed "s/[^ ]*[[:space:]]*//")
export FSTYPE=$(lsblk -l -o name,fstype|grep ^$ROOTNAME|sed "s/[^ ]*[[:space:]]*//")
ROOTDEVICE=/dev/$(lsblk -l -o name,pkname|grep ^$ROOTNAME|sed "s/[^ ]*[[:space:]]*//")
#PREV_GRUB_DISABLE_OS_PROBER=$(grep 'GRUB_DISABLE_OS_PROBER' /etc/default/grub | cut -d  '=' -f 2)
#sed -i "s/GRUB_DISABLE_OS_PROBER=.*/GRUB_DISABLE_OS_PROBER=\"true\"/g" /etc/default/grub >/dev/null 2>&1

        flag=$1
        flagr=$2
        flagw=$3
        flagf=$4

		if [ $# -gt 4 ] ; then
			echo "`eval_gettext 'ERROR: Too many arguments'`"
			usage
		fi

        if [[ $flag = "install" ]]; then
			export flag="install"
        elif [[ $flag = "upgrade" ]]; then
			export flag="upgrade"
		else
			usage
        fi

        #if switch is unknown or if asking for help
		if [[ $flagr = "help" ]] || [[ $flag = "h" ]]; then
			usage  
	    elif [[ $flagr = "generic" ]]; then
			export flagr="generic"
		else
			usage
		fi

       if [ -z "$flagw" ]; then
			export WAIT=10
	   else
	        export WAIT=$flagw
	   fi

       if [ -z "$flagf" ]; then
			#export flagf="ext4"
			export flagf=$FSTYPE
	   elif [ "$flagf" = "ext2" ]; then
			export flagf="ext2"
		elif [ "$flagf" = "ext3" ]; then
			export flagf="ext3"
		elif [ "$flagf" = "ext4" ]; then
			export flagf="ext4"
		elif [ "$flagf" = "btrfs" ]; then
			export flagf="btrfs"
		elif [ "$flagf" = "jfs" ]; then
			export flagf="jfs"
		elif [ "$flagf" = "reiserfs" ]; then
			export flagf="reiserfs"
		elif [ "$flagf" = "xfs" ]; then
			export flagf="xfs"
		else
			usage
		fi
}

execute_script(){
if [ -z "$startdir" ]; then
	startdir="$(pwd)"
	export startdir
fi

export ROOTUUID="$(findmnt -no uuid /)"


#hugemoduleslist="loop:xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:mmc-core:mmc-block:sdhci:sdhci-pci:sdhci-acpi:usb-storage:hid:usbhid:i2c-hid:hid-generic:hid-apple:hid-asus:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:crc32c-intel:fuse"
#moduleslist="loop:xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:mmc-core:mmc-block:sdhci:sdhci-pci:sdhci-acpi:usb-storage:hid:usbhid:i2c-hid:hid-generic:hid-apple:hid-asus:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:mptbase:mptscsih:mptspi:jbd2:mbcache:crc32c_intel:crc32c_generic:fuse:ext2:ext3:ext4:xfs:reiserfs:jfs:btrfs:isofs:fat:nls_cp437:nls_iso8859-1:msdos:vfat:ntfs"
moduleslist="squashfs:overlay:loop:efivarfs:xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:mmc-core:mmc-block:sdhci:sdhci-pci:sdhci-acpi:usb-storage:hid:usbhid:i2c-hid:hid-generic:hid-apple:hid-asus:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:mbcache:jbd2:mptscsih:mptspi:jbd:crc32c_intel:crc32c_generic:fuse:ext2:ext3:ext4:xfs:reiserfs:jfs:btrfs:isofs:fat:nls_cp437:nls_iso8859-1:msdos:vfat:ntfs:exfat:virtio_ring:virtio:virtio_blk:virtio_balloon:virtio_pci:virtio_pci_modern_dev:virtio_net:zstd_compress:lz4hc_compress:lz4_compress:rtsx_pci:rtsx_pci_sdmmc:uas"

#clear
#packages_dir contain packages.txz
packagesdirectory=$startdir/packages_dir
mkdir -p $packagesdirectory
slapt-get --clean
slapt-get -u
if [ "$flagr" == "generic" ]; then
	if [ `uname -m` == "x86_64" ]; then
		slapt-get -i --reinstall -d kernel-headers kernel-generic
	else
		slapt-get -i --reinstall -d kernel-headers kernel-generic
	fi
fi

if [ `uname -m` == "x86_64" ]; then
	cp `find /var/slapt-get/ -type f -name "kernel-headers*"` $packagesdirectory
	if [ "$flagr" == "generic" ]; then
		cp `find /var/slapt-get/ -type f -name "kernel-generic*"` $packagesdirectory
	fi	
	
	if [ "$flagr" == "generic" ]; then
		cd $packagesdirectory
		f=`ls kernel-generic*.txz`
		kv=`echo $f | cut -d'-' -f 3`
		cd $startdir
	fi
else
	cp `find /var/slapt-get/ -type f -name "kernel-headers*"` $packagesdirectory
	if [ "$flagr" == "generic" ]; then
		cp `find /var/slapt-get/ -type f -name "kernel-generic*"` $packagesdirectory
	fi
	
	if [ "$flagr" == "generic" ]; then
		cd $packagesdirectory
		f=`ls kernel-generic*.txz`
		kv=`echo $f | cut -d'-' -f 3`
		cd $startdir
	fi
fi

if [ -f /etc/lsb-release ]; then
	sed -i "s/DISTRIB_DESCRIPTION=.*/DISTRIB_DESCRIPTION='Slackel Linux $kv'/" /etc/lsb-release
fi

export SLACKELVERSION="Slackel Linux"

if [ "$flag" == "install" ]; then
	installpkg $packagesdirectory/*
	#export kv=`ls -l /boot/vmlinuz | cut -f2 -d'>' | sed s/^[^0-9]*//`
	export kv=`ls -l /boot/vmlinuz | cut -f2 -d'>' | cut -f2 -d'-'`
	(cd /boot
	rm /boot/vmlinuz-huge /boot/vmlinuz-huge-smp /boot/vmlinuz-generic /boot/vmlinuz-generic-smp >/dev/null 2>&1
	rm -rf /boot/initrd* >/dev/null 2>&1
	for KERNEL in `ls vmlinuz-*`; do
		#kvv=`echo $KERNEL | cut -f2 -d'>' | sed s/^[^0-9]*//`
		kvv=`echo $KERNEL | cut -f2 -d'>' | cut -f2 -d'-'`
		INITRD=initrd-${kvv}.gz
		moduleslist=$moduleslist
		echo "Creating initrd $INITRD"
		mkinitrd -c -f $flagf -u -w $WAIT -o /boot/$INITRD -r UUID=$ROOTUUID -k $kvv -m $moduleslist >/dev/null 2>&1
		rm -rf /boot/initrd-tree/ 
	done
	)
	rm /boot/vmlinuz-huge /boot/vmlinuz-huge-smp /boot/vmlinuz-generic /boot/vmlinuz-generic-smp >/dev/null 2>&1
	rm -rf $packagesdirectory
elif [ "$flag" == "upgrade" ]; then
	upgradepkg $packagesdirectory/*
	#export kv=`ls -l /boot/vmlinuz | cut -f2 -d'>' | sed s/^[^0-9]*//`
	export kv=`ls -l /boot/vmlinuz | cut -f2 -d'>' | cut -f2 -d'-'`
	(cd /boot
	rm /boot/vmlinuz-huge /boot/vmlinuz-huge-smp /boot/vmlinuz-generic /boot/vmlinuz-generic-smp >/dev/null 2>&1
	rm -rf /boot/initrd* >/dev/null 2>&1
	for KERNEL in `ls vmlinuz-*`; do
			#kvv=`echo $KERNEL | cut -f2 -d'>' | sed s/^[^0-9]*//`
			kvv=`echo $KERNEL | cut -f2 -d'>' | cut -f2 -d'-'`
			INITRD=initrd-${kvv}.gz
			moduleslist=$moduleslist
			echo "Creating initrd $INITRD"
			mkinitrd -c -f $flagf -u -w $WAIT -o /boot/$INITRD -r UUID=$ROOTUUID -k $kvv -m $moduleslist >/dev/null 2>&1
			rm -rf /boot/initrd-tree/
	done
	)
	rm /boot/vmlinuz-huge /boot/vmlinuz-huge-smp /boot/vmlinuz-generic /boot/vmlinuz-generic-smp >/dev/null 2>&1
	rm -rf $packagesdirectory
fi
}

UUIDify(){
#!/bin/sh
#
#   UUIDify (Version 1.0):
#
#     UUIDify /etc/fstab entries.  Output will be written to stdout.
#
#
#   Important note:
#
#     Make sure you review the output of this script before applying
#     it to your /etc/fstab. Blindly running: UUIDify.sh >/etc/fstab
#     would be a mistake!
#

file=${1:-/etc/fstab}

if [ "$file" != "-" ] && [ -r "$file" ]; then
    exec < "$file"
else
    echo "Could not read input file: $file" 1>&2
    exit 1
fi

if [ ! -r /run/blkid/blkid.tab ]; then
    if [ "$( id -u )" -eq 0 ]; then
	/sbin/blkid >/dev/null || exit 1
    else
	echo 'UUIDify requires a blkid cache file when run by a non-superuser id.' 1>&2
	echo 'Please run blkid as root user and re-run.' 1>&2
	exit 1
    fi
fi

while read fs_spec rest
do
    case "$fs_spec" in
	/dev/sd*|/dev/nvme*) uuid_spec=$( /sbin/blkid -s UUID "$fs_spec" )
		 uuid_spec=${uuid_spec#*: }
		 uuid_spec=${uuid_spec//\"/}
		 if [ "$uuid_spec" ]; then
		     printf "%-44s %s\n" "$uuid_spec" "$rest"
		 else
		     printf "%-44s %s\n" "$fs_spec" "$rest"
		 fi
		 ;;
	\#*)     printf "%s\n" "$fs_spec $rest" ;;
	*)       printf "%-44s %s\n" "$fs_spec" "$rest" ;;
    esac
done

################################################################# End. #

}

update_fstab(){
echo "updating fstab"	

if [ ! -f /etc/fstab.orig ]; then
	cp /etc/fstab /etc/fstab.orig
fi
	
	UUIDify > /tmp/dummy
	mv /tmp/dummy /etc/fstab	
}

generate_grub_cfg(){
echo "Creating /boot/grub/grub.cfg"	
cat << EOF > /boot/grub/grub.cfg
#set menu_color_normal=white/black
#set menu_color_highlight=white/blue

#terminal_output console
set timeout=10
#play 480 262 1 330 1 392 1 523 1
### BEGIN background setup ###
function load_video {
  if [ x = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
}
set menu_color_normal=white/black
set menu_color_highlight=white/blue

insmod part_gpt
insmod ext2
search --no-floppy --fs-uuid --set=root $ROOTUUID

if loadfont /boot/grub/fonts/unicode.pf2 ; then
  set gfxmode=auto
  load_video
  insmod gfxterm
  set locale_dir=/boot/grub/locale
  set lang=en_US
  insmod gettext
fi

terminal_output gfxterm
insmod part_gpt
insmod ext2

search --no-floppy --fs-uuid --set=root $ROOTUUID
insmod png
background_image -m stretch /boot/grub/slackel.png
EOF
(cd /boot
for KERNEL in `ls vmlinuz-*`; do
	#kvv=`echo $KERNEL | cut -f2 -d'>' | sed s/^[^0-9]*//`
	kvv=`echo $KERNEL | cut -f2 -d'>' | cut -f2 -d'-'`
	INITRD=initrd-${kvv}.gz
	
echo "
menuentry 'Boot $SLACKELVERSION kernel ${KERNEL}' {
	echo "Starting $SLACKELVERSION kernel ${KERNEL}.  Please wait..."
	insmod part_gpt
	insmod part_msdos
	insmod btrfs
	insmod f2fs
	insmod ext2
	insmod jfs
	insmod reiserfs
	insmod xfs
	insmod all_video
	search --fs-uuid --set=root $ROOTUUID
	linux /boot/${KERNEL} root=UUID=$ROOTUUID ro
	initrd /boot/$INITRD
}
" >> /boot/grub/grub.cfg
done
)

sed -i "s/GRUB_DISABLE_OS_PROBER=.*/GRUB_DISABLE_OS_PROBER=\"true\"/" /etc/default/grub
}

init
checkoptions $@
execute_script
update_fstab
generate_grub_cfg
echo "All jobs done."
