#!/bin/bash
##################################################################################
# Kanotix-Update-Script v0.1.2 by Andreas Loibl <andreas@andreas-loibl.de>
##################################################################################

#################### Default Settings ####################
WITHOUT_LIST="/etc/fstab
/etc/mtab
/etc/passwd
/etc/shadow
/etc/hostname
/etc/mailname
/etc/hosts
/etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_dsa_key
/home
/root"

#################### Command Line Arguments####################
while [ "$1" ]
do
    case $1 in
    -l|--exclude-list)
        shift
        if [ -e "$1" ]; then
            WITHOUT_LIST="$(cat "$1")"
        else
            echo "ERROR: '$1': File not found"
            exit 1
        fi
        ;;
    -s|--show-exclude-list)
        echo "$WITHOUT_LIST"
        exit 0
        ;;
    -bl|--boot-loader)
        shift
        case $1 in
            grub|lilo)
                BOOT_LOADER="$1"
                ;;
            *)
                echo "Invalid Bootloader: $1"
                exit 1
                ;;
        esac
        ;;
    -bw|--boot-where)
        shift
        case $1 in
            mbr|partition)
                BOOT_WHERE="$1"
                ;;
            *)
                echo "Invalid Bootloader-Target: $1"
                exit 1
                ;;
        esac
        ;;
    -f|--force|--non-interactive)
        NO_ASK=1
        ;;
    /dev/*)
        ROOT_DEV="$1"
        ROOT_MP="/mnt/$(basename "$1")"
        ;;
    /mnt/*)
        ROOT_MP="$1"
        ROOT_DEV="/dev/$(basename "$1")"
        ;;
    hd*|sd*|ide*)
        ROOT_MP="/mnt/$1"
        ROOT_DEV="/dev/$1"
        ;;
    esac
    shift
done

if [ -z "$ROOT_DEV" -o -z "$ROOT_MP" -o ! -e "$ROOT_DEV" -o ! -e "$ROOT_MP" ]; then
echo "Usage: $0 [Options] [Root-Partition]

[Options]
    -l filename, --exclude-list filename
                Use the exclude-list from the specified file.
                File format: One Path per Line, no comments (#)
    -s, --show-exclude-list
                Prints default exclude-list
    -bl (grub|lilo), --boot-loader (grub|lilo)
                Sets the Bootloader. Default: GRUB
    -bw (mbr|partition), --boot-where (mbr|partition)
                Sets the Bootloader-Target. Default: MBR
    -f, --force, --non-interactive
                The Update-Script doesn't ask you anything

[Root-Partition] can be in one of these formats:
    /dev/hda2
    /dev/sda1
    /mnt/hda2
    /mnt/sda1
    hda2
    sda1
"
exit 1
fi

####################  Function getFilesystem #################### 
############### Get the Filesystem of a Partition ############### 
function getFilesystem
{
	PARTITION="$1"
	MINOR="${PARTITION:(-1)}"
	DEVICE="${PARTITION:0:$[${#PARTITION}-1]}"
	
	FSTYPE="$(parted $DEVICE print | grep -e "^$MINOR" | awk '{print $5}')"
	echo "$FSTYPE"
}

#################### Check for root ####################
if [ $(id -u) -ne 0 ]; then
    echo "ERROR: You must be root to run this script!"
    exit 1
fi

#################### Check for Live-CD ####################
if [ ! -e /KNOPPIX/bin/ash ]; then
    echo "ERROR: $0 has to be executed from Live-CD"
    exit 1
fi

#################### Remount Root-Partition r/w ####################
if ! ( mount | egrep "^$ROOT_DEV" 2>/dev/null ); then
mount "$ROOT_DEV" 2>/dev/null
MOUNTED_BY_SCRIPT=1
fi
mount -o remount,rw "$ROOT_DEV" 2>/dev/null >/dev/null
BACKDIR="$(pwd)"
cd "$ROOT_MP"

#################### Check for Kanotix ####################
if [ ! -e "./etc/kanotix-version" ]; then
    echo "Error: No KANOTIX-Installation found on $ROOT_MP ($ROOT_DEV)"
    cd "$BACKDIR"
    [ $MOUNTED_BY_SCRIPT ] && umount "$ROOT_DEV"
    exit 1
else
    [ ! $NO_ASK ] && echo "Updating $(cat "./etc/kanotix-version") to $(cat "/etc/kanotix-version")..."
fi

#################### Add Mountpoints to rescue list ####################
WITHOUT_LIST="$WITHOUT_LIST
$(cat "./etc/fstab" | egrep -v "^([\s]*[^/].*|)$" | awk '{print $2}' | egrep -v "^(/|[^/].*)$")"

#################### Create a .knofig-File for the installer####################
ROOT_FSTYPE="$(getFilesystem "$ROOT_DEV")"
CONFIG_NAME="$(cat ./etc/kernel-pkg.conf | sed -ne 's/^maintainer := \(.*\)$/\1/ip')"
CONFIG_USER="$(cat ./etc/kernel-pkg.conf | sed -ne 's/^email := \([^@]*\).*$/\1/ip')"
CONFIG_HOST="$(cat ./etc/hostname)"
CONFIG_HDMAP="$(cat "/etc/fstab" | egrep -v "^([\s]*[^/].*|)$" | awk '{print $1 ":" $2}' | egrep  "^/dev/[hs]d..:/.")"
[ "$BOOT_LOADER" ] && CONFIG_BOOT_LOADER="$BOOT_LOADER" || CONFIG_BOOT_LOADER="grub"
[ "$BOOT_WHERE" ] && CONFIG_BOOT_WHERE="$BOOT_WHERE" || CONFIG_BOOT_WHERE="mbr"

cat <<END >$HOME/.knofig
REGISTERED=' SYSTEM_MODULE SYSTEM_TYPE HD_MODULE HD_FORMAT HD_FSTYPE HD_CHOICE HD_MAP HD_IGNORECHECK SWAP_MODULE SWAP_AUTODETECT NAME_MODULE NAME_NAME USER_MODULE USER_NAME USERPASS_MODULE USERPASS_CRYPT ROOTPASS_MODULE ROOTPASS_CRYPT HOST_MODULE HOST_NAME SERVICES_MODULE SERVICES_START BOOT_MODULE BOOT_LOADER BOOT_DISK BOOT_WHERE INSTALL_READY'

SYSTEM_MODULE='configured'
SYSTEM_TYPE='debian'

HD_MODULE='configured'
HD_FORMAT='no'
HD_FSTYPE='$ROOT_FSTYPE'
HD_CHOICE='$ROOT_DEV'
HD_MAP='$CONFIG_HDMAP'
HD_IGNORECHECK='yes'

SWAP_MODULE='configured'
SWAP_AUTODETECT='yes'

NAME_MODULE='configured'
NAME_NAME='$CONFIG_NAME'

USER_MODULE='configured'
USER_NAME='$CONFIG_USER'

USERPASS_MODULE='configured'
USERPASS_CRYPT='------------'

ROOTPASS_MODULE='configured'
ROOTPASS_CRYPT='------------'

HOST_MODULE='configured'
HOST_NAME='$CONFIG_HOST'

SERVICES_MODULE='configured'
SERVICES_START='kdm cupsys'

BOOT_MODULE='configured'
BOOT_LOADER='$CONFIG_BOOT_LOADER'
BOOT_DISK='no'
BOOT_WHERE='$CONFIG_BOOT_WHERE'
INSTALL_READY='yes'
END

if [ ! $NO_ASK ]; then
echo -e "The Installer-Configuration has been written to $HOME/.knofig.

The next step in the Updating-Process is to delete everything on the Root-Partition ($ROOT_MP),
exept some files (list them with $0 -s). These files will be backuped during the
Update and put back after the Installation of the new KANOTIX-Version.

Don't be afraid of 'File not found'- and 'Can't Overwrite'-Errors, this is normal.
Some directories can't be overwritten, but all the content will be moved to the right position
(if everything works well...)

\033\13301;31m!!!!ATTENTION!!!!\033\1330m    !!!!ATTENTION!!!!    \033\13301;31m!!!!ATTENTION!!!!\033\1330m    !!!!ATTENTION!!!!    \033\13301;31m!!!!ATTENTION!!!!\033\1330m
We are going to delete very much files on your Root-Partition. If anything goes
wrong here your data can be lost forever... You should better save your Data now...

IF YOU REALLY WANT TO CONTINUE ENTER 'Yes' now.

Do you want to continue?
"
read WIRKLICH
if [ "$WIRKLICH" != "Yes" ]; then
    echo "You didn't enter 'Yes' (case-sensitive), so we exit here."
    exit 1
else
    echo "OK, now there's no way back ;-)"
    echo "Please wait a bit, the files are being deleted now..."
fi
fi

#################### Search for files to delete ####################
CMD="find . -depth"
IFS="
"

for WITHOUT in $WITHOUT_LIST
do
    if [ -d ".$WITHOUT" ]; then
        CMD="$CMD ! -path '.$WITHOUT' ! -path '.$WITHOUT/*'"
    else
        CMD="$CMD ! -path '.$WITHOUT'"
    fi
done

eval "$CMD ! -type d -exec rm '{}' \; 2>/dev/null"
[ ! $NO_ASK ] && echo "The files are deleted, now removing the directories..."
eval "$CMD -type d -exec rmdir '{}' \; 2>/dev/null"

#################### Everything is deleted now. ####################
[ ! $NO_ASK ] && echo "Everything is deleted now. Now the remaining files are backed up..."

#################### Backup the existing files ####################
mkdir kanotix-update
mv .* * kanotix-update

#################### Start the installer ####################
[ ! $NO_ASK ] && echo "Starting Kanotix-Installer..."
kanotix-installer --non-interactive 1>&2
if [ $? -ne 0 ]; then
    if [ ! $NO_ASK ]; then
        echo -ne "\a"
        echo -e "\033\13301;31mKanotix-Installer failed :-(\033\1330m"
        echo "Your data should be saved at $ROOT_MP/kanotix-update. If it isn't there... "
        echo "$0 exits now."
    fi
    exit 1
fi

#################### Put the backup back ####################
if ! ( mount | egrep "^$ROOT_DEV" 2>/dev/null ); then
    mount "$ROOT_DEV" 2>/dev/null
    MOUNTED_BY_SCRIPT=1
fi
mount -o remount,rw "$ROOT_DEV" 2>/dev/null >/dev/null
cd "$ROOT_MP/kanotix-update"
find . -type d -exec sh -c 'mv "{}" ".$(dirname "{}")"' \; 2>/dev/null
find . ! -type d -exec mv '{}' '.{}' \; 2>/dev/null
cd ..
rm -r "kanotix-update" 2>/dev/null
cd "$BACKDIR"
[ $MOUNTED_BY_SCRIPT ] && umount "$ROOT_DEV" 2>/dev/null

#################### Finished ;-) ####################
if [ ! $NO_ASK ]; then
    echo -e "\033\13301;32mKanotix is now updated. Please reboot now.\033\1330m"
    echo -ne "\a"
    sleep 0.2
    echo -ne "\a"
fi
exit 0
