#!/usr/bin/bash
#set -x
# Remove old kernels safely and cleanly using urpme.
#
# LISTK contains the list of kernels to analyse
# The script keeps NBK most recent kernels
# (c) Pierre Jarillon - 2018-04-03 - 2021-11-27
# (c) Jean-Baptiste Biernacki 2021
# (c) Barry C Jackson 2022-2026
####################################
#
######################### Functions #########################

# Perform translations
i18n() {
gettext "$prog" "$1"
}

# NEW: Detect if running on a LIVE system
is_live_system() {
    # Check for Mageia LIVE system
    if grep -q 'mgalive' /proc/cmdline 2>/dev/null; then
        sys_type="$(i18n "LIVE System")"
        return 0
    else
        sys_type="$(i18n "System")"
        return 1
    fi
}

# NEW: Get the oldest installed kernel (the original on LIVE systems)
get_original_kernel() {
    # Build grep pattern from LISTK (which includes user config + MLISTK)
    # Convert newline-separated list to grep -E pattern: kernel-desktop|kernel-server|...
    local pattern=$(echo "$LISTK" | tr '\n' '|' | sed 's/|$//')

    rpm -qa 'kernel-*' --queryformat '%{INSTALLTIME}\t%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | \
    grep -E "${pattern}" | \
    grep -Ev 'kernel-(firmware|headers|tools|doc|latest)' | \
    sort -n | \
    head -1 | \
    cut -f2
}

# Display -help
usage() {
echo "$(i18n "Usage: <remove-old kernels|rok> [-a] [-A 0|1] [-c] [-t] [-f 0-9] [-F 0-9] [-n number] [-N number] [-p] [-q] [-Q 0|1][-l] [-m] [-v] [-h|-?]")"
echo "$(i18n "    -a = automatic, no questions. Interactive if not specified. (must be root)")"
echo "$(i18n "    -A value = 1 or 0 to turn ON or OFF automatic weekly removal of kernels. (e.g. -A1)")"
echo "$(i18n "    -c = as automatic but also checks for CRON=1 in the cfg file or exits. (must be root)")"
echo "$(i18n "    -t = Test mode, nothing is removed, urpme is simulated. Note: As root config may be updated")"
echo "$(i18n "    -f value = number of the alternate .cfg file to use this time only. Exits if missing.")"
echo "$(i18n "    -F value = number of alt .cfg file to use. This changes the ALTCFG= setting in the main .cfg file.")"
echo "$(i18n "    -n value = number of kernels to keep this time only. (-n5 or -n 5 keep 5 kernels), Min=2, Default=3")"
echo "$(i18n "    -N value = number of kernels to keep. This changes the config file setting. (e.g. -N 5)")"
echo "$(i18n "    -p = preview the urpme commands which would be used.")"
echo "$(i18n "    -q = advanced mode, this time only - see man page.")"
echo "$(i18n "    -Q value = 1 or 0 (1 = ON) advanced mode, persistent. (e.g. -Q1)")"
echo "$(i18n "    -l = list the last 1000 lines of the log.")"
echo "$(i18n "    -m = mono. No colours in screen output.")"
echo "$(i18n "    -v = version.")"
echo "$(i18n "    -? or -h = show this help.")"
echo ""
echo "$(i18n "KEY for column 3:")"
echo "$(i18n "     U = currently (U)sed running kernel.")"
echo "$(i18n "     L = (L)IVE system original kernel - protected.")"  # NEW
echo "$(i18n "     V = keeping for (V)irtualbox. (only in advanced mode)")"
echo "$(i18n "     X = keeping for (X)tables-addons (only in advanced mode)")"
echo "$(i18n "     K = keeping for installed (K)ernel. (only advanced mode)")"
echo ""
echo "$(i18n "Standard Message explanations:")"
echo "     DEBUG   $(i18n "— Diagnostic information useful for developers.")"
echo "     INFO    $(i18n "— Information only. No action required.")"
echo "     WARNING $(i18n "— Warning of an unexpected or suspicious event.")"
echo "     ERROR   $(i18n "— An error occurred, program stopped.")"
echo "     FATAL   $(i18n "— A critical error occurred. Program stopped.")"
echo ""
}

# Function to check we are root or exit
chkroot() {
if (( UID > 0 )); then
   echo -e "${RemvCol}$(i18n "Must be root to edit configuration")${Normal}\n$(i18n "Tap spacebar")"
   read -r -n1; echo -en "${ClearLine}"
   exit 0
fi
}

# Get number of kernels in /boot as user or root without errors
get_NK() {
    find /boot -name EFI -prune -o -regextype egrep -regex '.*vmlinuz.*.mga([0-9]|[0-9][0-9])' -print | wc -l
}

# Function to handle -f or -F options
altcfg() {
cfgno=$1
# Called with f
if [[ $ed -ne 1 ]]; then
    # Check for cfg 0
    if (( cfgno == 0 )); then
        source "${maincfg}"
        ALTCFG="${cfgno}"
    else
        # If alt cfg file exists source it
        if [[ -f /etc/remove-old-kernels_"${cfgno}".cfg ]]; then
                source "/etc/remove-old-kernels_${cfgno}.cfg"
            ALTCFG=${cfgno}
        else
            echo -e "${RemvCol}$(i18n "No such alternative configuration file:")${Normal} /etc/remove-old-kernels_${cfgno}.cfg"
            exit 1
        fi
    fi
else
    # Called with F
    # If ALTCFG var is missing from the main .cfg file, add it
    if ! grep -qF "ALTCFG=" "${maincfg}"; then
        echo "ALTCFG=" >> "${maincfg}"
    fi
    # Switch back to .cfg 0
    if (( cfgno == 0 )); then
        /usr/bin/sed -i "s/ALTCFG=.*/ALTCFG=${cfgno}/" "${maincfg}"
        source "${maincfg}"; currcfg="${maincfg}"
    else
        # If alt cfg file exists
        if [[ -f /etc/remove-old-kernels_${cfgno}.cfg ]]; then
            # Add it in main .cfg
            /usr/bin/sed -i "s/ALTCFG=.*/ALTCFG=${cfgno}/" "${maincfg}"
            ALTCFG=${cfgno};
            currcfg="${cfgpath}${prog}_${ALTCFG}.cfg"
            source "$currcfg"
        else
            echo -e "${RemvCol}$(i18n "No such alternative configuration file:")${Normal} /etc/remove-old-kernels_${cfgno}.cfg"
            exit 1
        fi
    fi
fi
}

# Check cfg file(s) and source
chk_cfg() {
# Source main .cfg file if it exists, or issue warning and abort.
source ${maincfg} || { echo -e "${RemvCol}FATAL: $(i18n "Failed to read:")${Normal} ${maincfg}"; exit 1; }

# If an alt .cfg is set in main .cfg
if grep -qF "ALTCFG=" "${maincfg}" && (( ALTCFG > 0 )); then
    # Check it really exists
    if [[ -f "${cfgpath}${prog}_$ALTCFG.cfg" ]]; then
        # Set current cfg to it
        currcfg="${cfgpath}${prog}_${ALTCFG}.cfg"
        source "$currcfg"
    else
        echo -e "${RemvCol}$(i18n "Your alternative configuration file does not exist:")${Normal}/etc/remove-old-kernels_$ALTCFG.cfg\n$(i18n "Either replace it or set ALTCFG=0 in") /etc/remove-old-kernels.cfg"
        exit 1
    fi
fi

# The following config file checks need root to update files if needed
if (( UID == 0 )); then
# Check for CRON variable in config or add default. (Some users may have early versions)
    if ! grep -qF -e "CRON=" "${currcfg}"; then
        echo -e "\n# Allow cron to run remove-old-kernels. 0=OFF 1=ON.\nCRON=1" >> "${currcfg}"
    fi

# Update comment in config file if needed since $CRON change to 0|1
    /usr/bin/sed -i 's/^.*\blower case\b.*$/# Allow cron to run remove-old-kernels. 0=OFF 1=ON./' "${currcfg}"

# Check for CRON set to old y/n values and update cfg
    if  (( ${#CRON} == 1 )) && [[ "ny" =~ $CRON ]]; then
        [[ $CRON == y ]] && CRON=1
        [[ $CRON == n ]] && CRON=0
        /usr/bin/sed -i "s/CRON=.*/CRON=${CRON}/" "${currcfg}"
    fi
fi
}

################ Main program starts here #################
# Do not edit the values below unless you know 'exactly' what you are doing.
# You can pass parameters on the command line to acheive similar functionality,
# or edit the configuration file/s, See man rok or rok -h for more information.

NBK=3      # Default number of kernels to keep.
DEBUG=0    # 1 for test mode, urpme is simulated and not applied
MODE="I"   # mode A)utomatic, I)nteractve (DO NOT CHANGE THIS)
VISU=0     # If VISU=1, show commands which can be used
LANGUAGE="${LANG}:${LANGUAGE}"

# Colours for display     Defaults                  Used for
Normal="\e[0m"          # System default f/g colour
KeepCol="\e[92m"        # Light Green               Keep text
RemvCol="\e[91m"        # Light Red                 Remove text
InfoCol="\e[33m"        # Orange                    Information text
HdBgCol="\e[102;30m"    # Light Green Background    Heading background
WarnBgCol="\e[101m"     # Light Red Background      Warnings in heading
ClearLine="\r\e[2K"     # Clear the line

# List of kernel types to include.
# This list is merged with LISTK if it exists in the .cfg file in use.
MLISTK="\
kernel-desktop
kernel-desktop-devel
kernel-linus
kernel-linus-devel
kernel-linus-source
kernel-lts-desktop
kernel-lts-desktop-devel
kernel-lts-server
kernel-lts-server-devel
kernel-lts-source
kernel-mainline-desktop
kernel-mainline-desktop-devel
kernel-mainline-source
kernel-server
kernel-server-devel
kernel-source
kernel-stable-desktop
kernel-stable-desktop-devel
kernel-stablenew-desktop
kernel-stablenew-desktop-devel
kernel-stablenew-source
kernel-stable-server
kernel-stable-server-devel
kernel-stable-source
"
prog="remove-old-kernels"
cfgpath="/etc/"
maincfg="${cfgpath}${prog}.cfg"
currcfg="${maincfg}"

# Check for -h option before running chk_cfg (issue10)
o=$(echo "$1"|cut -d- -f2)
[[ "$o" == "?" ]] && o="h"
if (( ${#@} == 1 )) && [[ "h" =~ $o ]]; then
        usage; exit 0
fi

# Check dnf limit before option parsing
dnfNBK=0; dnfmsg=false
[[ -f /etc/dnf/dnf.conf ]] && dnfNBK=$(grep "installonly_limit=" /etc/dnf/dnf.conf|cut -d= -f2)

# Run all config file checks before option parsing
chk_cfg

# NEW: Merge LISTK early so it's available for LIVE detection
# Check for LISTK and either create it or merge it with MLISTK.
if (( ${#LISTK} > 0 )); then
    LISTK="$(echo "$LISTK$MLISTK"|sort -u)"
else
    LISTK="$(echo "$MLISTK"|sort -u)"
fi

# Parse command line options which take precedence over script and cfg file
DESKTOP_LAUNCH=0
if (( ${#} > 0 )) ; then
     while getopts aA:ctf:F:plmvn:N:qQ:d?h-: NAME; do
        case ${NAME} in
            a)  MODE="A";
                ;;
            A)  chkroot
                # Allow y/n and 0/1 for compatability with older versions
                CRONN=${OPTARG}
                if [[ ${#CRONN} = 1 ]] && [[ "01ny" =~ $CRONN ]]; then
                    if [[ "ny" =~ $CRONN ]]; then
                        echo "$(i18n "Please use 0 or 1 for OFF and ON")"
                        exit 0
                    else
                        /usr/bin/sed -i "s/CRON=.*/CRON=${CRONN}/" "${currcfg}" && CRON=$CRONN
                    fi
                else
                    echo "$(i18n "Bad input value")"; exit 1
                fi
                ;;
            c)  MODE="A" && (( ${#CRON} > 0 )) && [[ "1y" =~ $CRON ]] || exit 0
                ;;
            d)  DESKTOP_LAUNCH=1   # Internal flag - desktop menu launch
                ;;
            t)  DEBUG=1
                ;;
            f)  [[ ${OPTARG} =~ ^[0-9] ]] && (( ${#OPTARG} == 1 )) && altcfg "${OPTARG}"
                ;;
            F)  chkroot
                [[ ${OPTARG} =~ ^[0-9] ]] && (( ${#OPTARG} == 1 )) && ed=1 && altcfg "${OPTARG}"
                ;;
            p)  VISU=1
                ;;
            q)  QA=1
                ;;
            Q)  chkroot
                [[ ${OPTARG} =~ ^[0-1] ]] && (( ${#OPTARG} == 1 )) && QAN="${OPTARG}"
                if grep -qF "QA=" "${currcfg}"; then
                    /usr/bin/sed -i "s/QA=.*/QA=${QAN}/" "${currcfg}" && QA="${QAN}"
                else
                    echo "QA=${QAN}" >> "${currcfg}" && QA="${QAN}"
                fi
                ;;
            n)  is_live_system && { echo -e "${RemvCol}ERROR - $(i18n "In a LIVE system N is fixed.")${Normal}"; exit 0; }
                [[ ${OPTARG} =~ ^[0-9]+$ ]] && NBK="${OPTARG}"
                ;;
            N)  is_live_system && { echo -e "${RemvCol}ERROR - $(i18n "In a LIVE system N is fixed.")${Normal}"; exit 0; }
                chkroot
                NBKN=${OPTARG}
                if [[ $NBKN =~ ^[0-9]+$ ]] && (( NBKN >= dnfNBK )); then
                    /usr/bin/sed -i "s/NBK=.*/NBK=$NBKN/" "${currcfg}" && NBK="$NBKN"
                else
                    dnfmsg=1
                fi
                ;;
            l)  LOG=1
                tail -n1000 /var/log/remove-old-kernels.log && (( QA < 1 )) && { echo -e "\n$(i18n "Tap spacebar to exit")\n"; read -r -n1; echo -en "${ClearLine}"; }
                                ;;
            m)  Normal=""; RemvCol=""; KeepCol=""; InfoCol=""; HdBgCol=""; WarnBgCol=""; ClearLine=""
                ;;
            v)  printf '%s'"$(rpm -q remove-old-kernels)\n"
                exit 2
                ;;
            h|?) usage
                ;;
         esac
    done
fi

# Don't allow NBK < 2 whether it comes from CLI, script edit, config file or the moon
if (( NBK < 2 )); then
    NBK=2
fi

# Only use greeting in interactive mode not in QA mode
if [[ "$MODE" == "I" ]] && (( QA < 1 )); then
    clear
    echo -e "                        $(i18n "Welcome to 'remove-old-kernels' Interactive")\n"
fi

# Don't run main program after -l or -h/-? options in QA mode
if (( QA == 1 )); then
    if (( LOG == 1 )); then
       exit 0
    fi
fi

# Use dnf kernel 'number to keep' if installed and greater than ours
if (( dnfNBK > NBK )) || (( dnfmsg == 1 )); then
    NBK=$dnfNBK
    dnfmssg="${InfoCol} INFO: $(i18n "Number to keep is restricted to ")${dnfNBK}\
$(i18n ", by the dnf 'installonly_limit' set in /etc/dnf/dnf.conf")${Normal}"
fi

# Get info for status message
if (( CRON == 1 )); then autostat="1"; else autostat="${Normal}${WarnBgCol}0${HdBgCol}"; fi
if (( QA == 1 )) ; then qamssg="| Q "; fi
if (( ALTCFG > 0 )); then cfgmssg="|${Normal}${WarnBgCol}F:${ALTCFG}${HdBgCol} "; fi

# NEW: Detect LIVE system and get original kernel to protect
LIVE_MODE=0
PROTECT_KERNEL=""
if is_live_system; then
    LIVE_MODE=1
    PROTECT_KERNEL=$(get_original_kernel)
    if [ -n "$PROTECT_KERNEL" ]; then
        # Force NBK=1 for LIVE systems (only latest and original are bootable)
        NBK=1
    fi
fi

# Check that the running kernel is still installed: https://bugs.mageia.org/show_bug.cgi?id=31015
[[ -e /lib/modules/$(uname -r) ]] || { echo -e "${RemvCol}FATAL: $(i18n "Has the running kernel been uninstalled since last boot? - Aborting.")"; exit 1; }

# Get the full name of the current running kernel
CURK=$(rpm -qf /lib/modules/"$(uname -r)")

# Storage for the list of kernels to remove
TMPKTR=$(mktemp)

# Check storage usage on root partition
OCCDISK1=$(df -B 1M -l --output=used / | tail -n1 | awk '{ print $1 }')

# Pad translated strings for column 2
    keepstr="$(i18n "Keep")"
    remstr="$(i18n "Remove")"
    if (( ${#keepstr} != ${#remstr} )); then
        if (( ${#keepstr} > ${#remstr} )); then
            while (( ${#remstr} < ${#keepstr} )); do remstr="${remstr} "; done
        else
            while (( ${#remstr} > ${#keepstr} )); do keepstr="${keepstr} "; done
        fi
    fi

#========================= Analyse /boot/ =============================
NK=$(get_NK)
# In automatic mode exit immediately if kernels in boot <= number allowed to be removed
   [[ "$MODE" = "A" ]] && (( NK < NBK )) && exit 0

#================================ Show status ==============================

echo -e "${HdBgCol} ${sys_type}: $(cat /etc/mageia-release) | $(i18n "Kernels in") /boot/:${NK} | AUTO:$autostat | $(i18n "KEEP"):$NBK ${qamssg}${cfgmssg}${Normal} "

#================================= Analyse rpms =============================
# Get master list from rpm -qa --last
allkernels="$(rpm -qa --last|grep "kernel-")"

# Get the kernel version and release required by the installed virtualbox-flavour-latest
get_vbox_kern() {
if echo "$allkernels"|grep -q "virtualbox-${kernelType}-latest"; then
     vb_latest_ver=$(echo "$allkernels"|cut -d' ' -f1|grep "virtualbox-${kernelType}-latest"|cut -d- -f5-|rev|cut -d. -f2-|rev)
else
     qavkern=; return
fi
depkern=$(echo "$allkernels"|cut -d' ' -f1|grep "$vb_latest_ver"|grep -v latest|grep "virtualbox-kernel-[0-9]")
kern_ver=$(echo "$depkern"|cut -d- -f3-|cut -d- -f1)
kern_rel=$(echo "$depkern"|cut -d- -f5-|cut -d. -f1)
(( ${#kern_ver} > 0 )) && (( ${#kern_rel} > 0 )) && qavkern="${kern_ver}-${kern_rel}"
}

# Get the kernel version and release required by the installed xtables-addons-flavour-latest
get_xtables_kern() {
if echo "$allkernels"|grep -q "xtables-addons-${kernelType}-latest"; then
     xt_latest_ver=$(echo "$allkernels"|cut -d' ' -f1|grep kernel-|grep "xtables-addons-kernel"|grep "latest"|cut -d- -f6-|rev|cut -d. -f2-|rev)
else
     qaxkern=; return
fi
depkern=$(echo "$allkernels"|cut -d' ' -f1|grep "$xt_latest_ver"|grep "xtables-addons-kernel-[0-9]"|cut -d ' ' -f1)
kern_ver=$(echo "$depkern"|cut -d- -f4)
kern_rel=$(echo "$depkern"|cut -d- -f6 -|cut -d. -f1)
(( ${#kern_ver} > 0 )) && (( ${#kern_rel} > 0 )) && qaxkern="${kern_ver}-${kern_rel}"
}

# Keep the -devel package for any installed kernel package
depdev()  {
# Reset some vars
pkg=; kpkgname=; nnk=""
    # Is current pkg a -devel
    if echo "${installedKernelPackage}" | grep -q "\-devel"; then
        # Get matching kernel package name
        kpkgname=$(echo "${installedKernelPackage}"| /usr/bin/sed -e 's/\-devel//')
        # Find kernel in installed list without timestamp
        for pkg in $(echo "$allkernels"|cut -d ' ' -f1); do
            # Look through installed kernels for kernel package
            if [[ ${pkg} == "${kpkgname}" ]]; then
                nnk="K"; REMVBL=0
                # Is kernel flagged for removal?
                if  grep -q "$kpkgname" "${TMPKTR}" ; then
                    # Then this -devel is also removable
                    nnk=""; REMVBL=1
                fi
                # We are done here
                break
            fi
        done
    fi
}

# Exclude 'latest' packages from installed kernel list
rpmqaList=$(echo "$allkernels"|grep -v latest)

# Loop through kernel types in LISTK
for kernelType in ${LISTK}; do
    (( QA == 1 )) && get_vbox_kern && get_xtables_kern
    installedKernelCounter=0;
# Scan through installed kernels to match with kernel type in LISTK
    echo "$rpmqaList"|grep "${kernelType}-[0-9]"|while read -r installedKernel; do
# Clear these for each loop
        NOTA=""; REMVBL=1
# Increment installedKernelCounter
        installedKernelCounter=$(( installedKernelCounter + 1))

# Add heading if there exists at least one installedKernel of this kernelType
        if (( installedKernelCounter == 1 )) ; then
            echo -ne "\r ==> ${kernelType}"
            echo ""
        fi

# Remove time stamp
        installedKernelPackage="$(echo "${installedKernel}" | cut -d ' ' -f 1 )"

# Check for current kernel
        if (( $(echo "${installedKernel}" | grep -c "${CURK}") == 1 )) ; then
            NOTA="U"       # current kernel
            REMVBL=0       # not removable
        fi

# NEW: Check if this is the protected LIVE kernel
        if (( LIVE_MODE == 1 )) && [ -n "$PROTECT_KERNEL" ]; then
            if [ "$installedKernelPackage" = "$PROTECT_KERNEL" ]; then
                NOTA="${NOTA}L"    # LIVE original kernel
                REMVBL=0           # not removable
            fi
        fi

# Check if kernel is required by vbox latest kernel
        if (( QA == 1 )) && (( ${#qavkern} > 0 )) && (( $(echo "${installedKernel}" | grep -c "$qavkern") == 1 )); then
            NOTA="${NOTA}V"     # Required by VBox
            REMVBL=0            # not removable
        fi

# Check if kernel is required by xtables latest kernel
        if (( QA == 1 )) && (( ${#qaxkern} > 0 )) && (( $(echo "${installedKernel}" | grep -c "$qaxkern") == 1 )); then
            NOTA="${NOTA}X"     # Required by xtables
            REMVBL=0            # not removable
        fi

# If a kernel devel package has the corresponding kernel package keep it
        if (( QA == 1 )); then
            depdev
            NOTA="${NOTA}${nnk}"
        fi

# Pad NOTA to 4
        while (( ${#NOTA} < 4 )); do NOTA="${NOTA} "; done

# Pad installedKernelCounter (col 1) to 3
        while (( ${#installedKernelCounter} < 3 )); do installedKernelCounter="${installedKernelCounter} "; done

        if (( installedKernelCounter > NBK )); then
            if (( REMVBL != 1 )) ; then
                echo -e "\r ${installedKernelCounter}${KeepCol} : $keepstr: ${NOTA}: ${installedKernel} ${Normal}"
            else
                echo -e "\r ${installedKernelCounter}${RemvCol} : $remstr: ${NOTA}: ${installedKernel} ${Normal}"
                # Add package to removal list
                echo "${installedKernelPackage}" >> "${TMPKTR}"
            fi
        else
            echo -e "\r ${installedKernelCounter}${KeepCol} : $keepstr: ${NOTA}: ${installedKernel} ${Normal}"
        fi
    done
done

# Position 'in use' key under symbol below column 3
padUse=$((${#keepstr}+9)); padstr=""
while (( ${#padstr} < padUse )); do padstr="${padstr} "; done

echo -en "${ClearLine}"
echo -e "${padstr}${KeepCol}U${InfoCol} = $(i18n "In use now")${Normal}"
# NEW: Add LIVE key explanation
if (( LIVE_MODE == 1 )); then
    echo -e "${padstr}${KeepCol}L${InfoCol} = $(i18n "LIVE system original kernel")${Normal}"
fi
if (( ${#dnfmssg} > 0 ));then echo -e "${dnfmssg}"; fi

#================================= Mode of execution ===================

# Check there are kernels to remove
nbktr=$(grep -vc 'devel\|source' < "${TMPKTR}")
nbt=$(wc -l < "${TMPKTR}")
if (( nbt != 0 )) ; then
    # Check if we are in preview mode
    if (( VISU == 1 )); then
        plural="s"; (( nbt == 1 )) && plural=""
        # Get singular/plural message without getting obfuscated by gettext
        if [[ "$plural" == "s" ]]; then
            echo "$(i18n "Commands that would be used"):"
        else
            echo "$(i18n "Command that would be used"):"
        fi
        # Print out the kernel commands
        for f in $(tac "${TMPKTR}"); do
            echo "urpme ${f}"
        done
        echo "$(i18n "Tap spacebar to exit")"
        read -n1
        echo -en "${ClearLine}"
        # Delete temp file list of removeable kernels
        rm -f "${TMPKTR}"
        exit 0
    fi
        # Warn if we are not root and hang until spacebar hit
        if (( UID > 0 )); then
        echo -e "${RemvCol}$(i18n "Must be root to allow removal")${Normal}\n$(i18n "Tap spacebar")"
        read -r -n1; echo -en "${ClearLine}"
        exit 0
        fi
    if [[ "${MODE}" != "A" ]] ; then
        if (( DEBUG == 1 )) ; then
            echo -e "\n${KeepCol}>> $(i18n "Test mode is on - kernels will not be removed") <<${Normal}"
        fi
        plural="s"; (( nbktr == 1 )) && plural=""
        if [[ "$plural" == "s" ]]; then
            kernstr="$(i18n "kernels"):"
        else
            kernstr="$(i18n "kernel"):"
        fi
        if (( nbt == nbktr )); then
            read -p "$(i18n "Remove") ${nbt} $kernstr ? $(i18n "y/N/i (i=confirm for each)") " -n 1 response
        else
            read -p "$(i18n "Remove") ${nbt} (${nbktr} ${kernstr}) ? $(i18n "y/N/i (i=confirm for each)") " -n 1 response
        fi
        if [[ -z ${response} ]] ; then response="n" ; fi
            case ${response} in
                [Yy])
                    AUTO="--auto"
                    MODE="A"
                    echo -e " \n"
                    ;;
                [Ii])
                    AUTO="--auto"
                    MODE="I"
                    echo " $(i18n "interactive")"
                    ;;
                *)
                    echo -e "\n$(i18n "Aborted")\n"
                    rm -f "${TMPKTR}"
                    exit 0
                    ;;
            esac
    fi

#================================= Execution ===========================

    for installedKernelPackage in $(tac "${TMPKTR}") ; do
        if [[ ${MODE} = "I" ]] ; then    # --- interactive mode ---
            read -p "$(i18n "Remove") ${installedKernelPackage} ? $(i18n "y/N/q (q=quit)") " -n 1 response
            echo -e " \n"
            if [[ -z ${response} ]]; then
                response="N"
            fi
            case ${response} in
                [Yy])
                    if (( DEBUG == 1 )) ; then
                        echo -e "\n${InfoCol}DEBUG: $(i18n "Could execute: urpme") ${AUTO} ${installedKernelPackage}${Normal}"
                        ((nbt--))
                    else
                        urpme "${installedKernelPackage}"
                        ((nbt--))
                    fi
                    ;;
                [qQ])
                    echo -e "\n$(i18n "Aborted")"
                    rm -f "${TMPKTR}";
                    exit 0
                    ;;
                   *)
                    echo " "
                    ;;
            esac
        else             # --- automatic mode ---
            AUTO="--auto"
            if (( DEBUG == 1 )) ; then
                echo -e "${InfoCol}DEBUG: $(i18n "Could execute: urpme") ${AUTO} ${installedKernelPackage}${Normal}"
                ((nbt--))
            else
                # --- automatic execution ---
                # preload y and CR in auto mode
                echo -ne 'y\n' | urpme "${AUTO}" "${installedKernelPackage}"
                ((nbt--))
            fi
        fi
    done
        NK=$(get_NK)
        OCCDISK2=$(df -B 1M -l --output=used / | tail -n1 | awk '{ print $1 }')
        echo -e "${HdBgCol} $(i18n "Gain"):$((OCCDISK1 - OCCDISK2)) MB - $(i18n "Kernels in") /boot/: ${NK} ${Normal}"
fi

[[ $MODE == "I" ]] && (( QA < 1 )) && { echo "$(i18n "Tap spacebar to exit")"; read -n1; echo -en "${ClearLine}"; }

# NEW: In QA mode launched from desktop, pause before closing
if (( QA == 1 )) && (( DESKTOP_LAUNCH == 1 )) ; then
    echo "$(i18n "Tap spacebar to exit")"
    read -n1
    echo -en "${ClearLine}"
fi

rm -f "${TMPKTR}"

# Run again if some removable kernels are left
(( QA = 1 )) && exit 0              # Always just exit in QA mode if in terminal
(( UID > 0 )) && exit 0             # Not root user so exit
[[ ${MODE} != "I" ]] &&  exit 0     # Auto so exit
(( nbt > 0 )) &&  ${0}   # Root user and interactive so run again if removable packages left
