#!/bin/sh
# slitaz-installer - SliTaz GNU/Linux installer.
#
# So this is SliTaz installer using dialog boxes. All the comments are in
# English but displayed messages are in French. The script starts with a
# few main variables, then all the functions and then a sequence of functions.
#
# (C) 2007-2008 SliTaz - GNU General Public License v3.
#
# Author : Christophe Lincoln <pankso@slitaz.org>
#
VERSION=1.0

if [ "$1" = "gui" ]; then
	: ${DIALOG=tazdialog}
else
	: ${DIALOG=dialog}
fi

# Installer actions can be specified on cmdline (install or upgrade).
if [ "$1" = "upgrade" ]; then
	ACTION=$1
else
	ACTION=install
fi

# We need to know cdrom device and kernel version string to copy files.
DRIVE_NAME=`cat /proc/sys/dev/cdrom/info | grep "drive name" | cut -f 3`
CDROM=/dev/$DRIVE_NAME
KERNEL=vmlinuz-`uname -r`
TARGET_ROOT=/mnt/target
LOG=/var/log/slitaz-installer.log
BACKLIST="SliTaz GNU/Linux installer"

#######################
# Installer functions #
#######################

# Messages language setting.
set_messages()
{
	case $LANG in
		de*)
			. /usr/share/slitaz/messages/de/installer.msg ;;
		fr*)
			. /usr/share/slitaz/messages/fr/installer.msg ;;
		hu*)
			. /usr/share/slitaz/messages/hu/installer.msg ;;
		pt*)
			. /usr/share/slitaz/messages/pt/installer.msg ;;
		*)
			. /usr/share/slitaz/messages/en/installer.msg ;;
	esac
}

# Display error message.
error_message()
{
	$DIALOG --title " Error " \
		--colors --backtitle "$BACKLIST" \
		--clear --msgbox "\n$ERROR_MSG" 18 70
}

# Exit install if user is not root.
check_root()
{
	if test $(id -u) != 0 ; then
	ERROR_MSG="\
[\Z6en\Zn] You must be root administrator to start SliTaz installer, please \
use 'su' to get a root SHell and restart installation.\n\n
[\Z6fr\Zn] Vous devez tre root pour installer SLiTaz GNU/Linux. Vous pouvez \
utiliser 'su' suivi du mot de passe administrateur pour devenir root \
et relancer l'installation."
		error_message
		exit 0
	fi
}

# This function is used after each screen to contine or abort install.
check_retval()
{
	case $retval in
		0)
			continue ;;
		1)
			echo -e "\nVoluntary exit.\n" && exit 0 ;;
		3)
			continue ;;
		255)
			echo -e "ESC pressed.\n" && exit 0 ;;
	esac
}

# Start install with basic information.
start_installer()
{
	$DIALOG --title " Install or Upgrade " \
		--backtitle "$BACKLIST" \
		--extra-button --extra-label "Upgrade" \
		--yes-label "Install" \
		--no-label "Quit" \
		--clear --colors --yesno "$START_INSTALL_MSG" 18 70
	retval=$?
		case $retval in
		0)
			ACTION=install ;;
		1)
			echo -e "\nVoluntary exit.\n" && exit 0 ;;
		3)
			ACTION=upgrade ;;
		255)
			echo -e "ESC pressed.\n" && exit 0 ;;
	esac
	echo "start_installer: `date`" > $LOG
}

# Mount cdrom and verify if it's really SliTaz CD.
mount_cdrom()
{
	ERROR_MSG=""
	(
	echo "XXX" && echo 30
	echo -e "\nCreating mount point (/media/cdrom)..."
	echo "XXX"
	mkdir -p /media/cdrom
	sleep 1
	echo "XXX" && echo 60
	echo -e "\nMounting cdrom ($CDROM)..."
	echo "XXX"
	mount -t iso9660 $CDROM /media/cdrom 2>>$LOG
	echo "XXX" && echo 90
	echo -e "\nChecking installation media..."
	echo "XXX"
	sleep 2
	) |
	$DIALOG --title " Mounting cdrom " \
		--backtitle "$BACKLIST" \
		--gauge "Preparing the installation media..." 18 70 0
	# Exit with error msg if no rootfs.gz found.
	if [ ! -f /media/cdrom/boot/rootfs.gz ]; then
		ERROR_MSG="$MOUNT_CDROM_ERROR_MSG"
		error_message
		echo "missing: /media/cdrom/boot/rootfs.gz" >>$LOG
		exit 1
	fi
}

# Display a list of available partitions.
fdisk_list()
{
	LIST_PARTITIONS=`fdisk -l | grep ^/dev | sed s/'e Win95'/'e'/g`
	$DIALOG --title " Partition tables " \
		--backtitle "$BACKLIST" \
		--clear --msgbox "\n
Available partitions :\n\n
$LIST_PARTITIONS" 18 70
}

# We need a partition to install to (inputbox).
ask_for_target_dev()
{
	exec 3>&1
	TARGET_DEV=`$DIALOG --title " Root Partition " \
		--backtitle "$BACKLIST" --clear \
		--extra-label "List" --extra-button \
		--colors --inputbox "$ASK_FOR_TARGET_DEV_MSG" 18 70 2>&1 1>&3`
	retval=$?
	exec 3>&-
	check_retval
	# Display list and come back.
	if [ "$retval" = "3" ]; then
		fdisk_list
		ask_for_target_dev
	fi
	# Empty value.
	if [ -z $TARGET_DEV ]; then
		ask_for_target_dev
	fi
	set_messages
	# Check if specified device exists in /proc/partitions.
	DEV_NAME=${TARGET_DEV#/dev/}
	if cat /proc/partitions | grep -q $DEV_NAME; then
		if [ "$DEV_NAME" = "$TARGET_DEV" ]; then
			TARGET_DEV="/dev/$DEV_NAME"
		fi
		echo "ask_for_target_dev: $TARGET_DEV" >>$LOG
	else
		ERROR_MSG="Partition \Z2$TARGET_DEV\Zn doesn't exist."
		error_message
		ask_for_target_dev
	fi
}

# Mkfs if needed/wanted.
ask_for_mkfs_target_dev()
{
	$DIALOG --title " Format " \
		--backtitle "$BACKLIST" \
		--clear --colors --yesno "$ASK_FOR_MKFS_TARGET_DEV_MSG" 18 70
	retval=$?
	case $retval in
		0)
			MKFS_TARGET_DEV="ext3"
			echo "mkfs_target_dev: ext3" >>$LOG ;;
		1)
			CLEAN="clean"
			echo "mkfs_target_dev: clean" >>$LOG ;;
		255)
			echo -e "ESC pressed.\n" && exit 0 ;;
	esac

}

# Mount and mkfs with progress.
prepare_target_dev()
{
	(
	echo "XXX" && echo 30
	echo -e "\nPreparing target partition..."
	echo "XXX"
	# Mount point can be already used.
	if mount | grep -q $TARGET_ROOT; then
		umount $TARGET_ROOT 2>$LOG
	fi
	sleep 2

	if [ "$MKFS_TARGET_DEV" == "ext3" ]; then
		echo "XXX" && echo 60
		echo -e "\nExecuting mkfs.ext3 on $TARGET_DEV"
		echo "XXX"
		mkfs.ext3 $TARGET_DEV >>$LOG 2>>$LOG
	else
		echo "XXX" && echo 60
		echo -e "\nThe partition ($TARGET_DEV) will be cleaned..."
		echo "XXX"
		sleep 2
	fi

	echo "XXX" && echo 90
	echo -e "\nCreating mount point: $TARGET_ROOT"
	echo "XXX"
	mkdir -p $TARGET_ROOT
	sleep 2

	) |
	$DIALOG --title " Prepare the target " \
		--backtitle "$BACKLIST" \
		--gauge "Target in preparation..." 18 70 0
	# Mount target.
	mount $TARGET_DEV $TARGET_ROOT >>$LOG 2>>$LOG
}

# Ask for hostname before installing files.
ask_for_hostname()
{
	exec 3>&1
	HOSTNAME=`$DIALOG --title " Hostname " \
		--backtitle "$BACKLIST" --clear \
		--colors --inputbox "$ASK_FOR_HOSTNAME_MSG" 18 70 "slitaz" 2>&1 1>&3`
	retval=$?
	exec 3>&-
	check_retval
	# Empty value.
	if [ -z $HOSTNAME ]; then
		HOSTNAME="slitaz"
	fi
}

# Get a clean target device (15%).
clean_target()
{
	if [ "$CLEAN" == "clean" ]; then
		echo "XXX" && echo 15
		echo -e "\nCleaning the root partition ($TARGET_DEV)..."
		echo "XXX"
		# Keep /home in case of reinstall.
		cd $TARGET_ROOT
		for dir in *
		do
			case "$dir" in
				home)
					mv $TARGET_ROOT/home $TARGET_ROOT/home.bak
					echo "keeping /home found on: $TARGET_DEV" >>$LOG ;;
				lost+found)
					continue ;;
				*)
					echo "removing target: $dir" >>$LOG
					rm -rf $dir 2>>$LOG ;;
			esac
		done
		if [ -d $TARGET_ROOT/mklost+found ]; then
			mklost+found 2>>$LOG
		fi
	fi
	sleep 2
}

# Kernel is renamed to standard vmlinuz-$VERSION.
install_kernel()
{
	mkdir -p $TARGET_ROOT/boot
	cp /media/cdrom/boot/bzImage $TARGET_ROOT/boot/$KERNEL
	echo "install_kernel: $KERNEL" >> $LOG
	sleep 2
}

# Copy isolinux r/w files (not syslinux, some files are read only).
copy_bootloaders()
{
	if [ -d "/media/cdrom/boot/isolinux" ]; then
		mkdir -p $TARGET_ROOT/boot/isolinux
		cp -a /media/cdrom/boot/isolinux/*.cfg $TARGET_ROOT/boot/isolinux
		cp -a /media/cdrom/boot/isolinux/*.kbd $TARGET_ROOT/boot/isolinux
		cp -a /media/cdrom/boot/isolinux/*.txt $TARGET_ROOT/boot/isolinux
		cp -a /media/cdrom/boot/isolinux/*.bin $TARGET_ROOT/boot/isolinux
		cp -a /media/cdrom/boot/isolinux/*.msg $TARGET_ROOT/boot/isolinux
		cp -a /media/cdrom/boot/isolinux/*.lss $TARGET_ROOT/boot/isolinux
		cp -a /media/cdrom/boot/isolinux/*.c32 $TARGET_ROOT/boot/isolinux
	fi
}

# Extract lzma'ed or gziped rootfs.
extract_rootfs()
{
	cd $TARGET_ROOT
	(zcat rootfs.gz 2>/dev/null || lzma d rootfs.gz -so || \
	 cat rootfs.gz) 2>>$LOG | cpio -id 2>>$LOG > /dev/null
	rm -f rootfs.gz
	# unpack /usr (double check...)
	if ls etc/tazlito | grep -q ".extract"; then
		for i in etc/tazlito/*.extract; do
			[ -f "$i" ] && . $i /media/cdrom
		done
	fi
}

# /etc/skel (60%)
gen_etc_skel()
{
	# Maybe we don't have /home/hacker directory.
	if [ -d $TARGET_ROOT/home/hacker ]; then
		echo "XXX" && echo 60
		echo -e "\nCopying default user files (/etc/skel)..."
		echo "XXX"
		cp -a $TARGET_ROOT/home/hacker $TARGET_ROOT/etc/skel
	else
		echo "XXX" && echo 60
		echo -e "\nCreating directory (/etc/skel)..."
		echo "XXX"
		mkdir -p $TARGET_ROOT/etc/skel \
			$TARGET_ROOT/etc/Documents \
			$TARGET_ROOT/etc/skel/Images \
			$TARGET_ROOT/etc/skel/.local/bin \
			$TARGET_ROOT/etc/skel/.local/share
	fi
	sleep 2
}

# Pre configure freshly installed system (70 - 90%).
pre_config_system()
{
	cd $TARGET_ROOT
	# Restore backup of existing /home if exists.
	# (created by prepare_target_dev)
	if [ -d home.bak ]; then
		echo "XXX" && echo 75
		echo -e "\nThe restore directory: /home..."
		echo "XXX"
		rm -rf home
		mv home.bak home
		sleep 2
	fi
	# Add root device to CHECK_FS in rcS.conf to check filesystem
	# on each boot.
	echo "XXX" && echo 80
	echo -e "\nAdding $TARGET_DEV and CHECK_FS to file /etc/rcS.conf..."
	echo "XXX"
	sed -i s#'CHECK_FS=\"\"'#"CHECK_FS=\"$TARGET_DEV\""# etc/rcS.conf
	sleep 2
	# Set hostname.
	echo "XXX" && echo 85
	echo -e "\nConfiguring host name: $HOSTNAME"
	echo "XXX"
	echo $HOSTNAME > etc/hostname
	sleep 2
}

# Determine GRUB partition number and GRUB disk number.
grub_config()
{
	DISK_LETTER=${TARGET_DEV#/dev/[h-s]d}
	DISK_LETTER=${DISK_LETTER%[0-9]}
	GRUB_PARTITION=$((${TARGET_DEV#/dev/[h-s]d[a-z]}-1))
	for disk in a b c d e f g h
	do
		nb=$(($nb+1))
		if [ "$disk" = "$DISK_LETTER" ]; then
			GRUB_DISK=$(($nb-1))
			break
		fi
	done
	GRUB_ROOT="(hd${GRUB_DISK},${GRUB_PARTITION})"
	# Create the target GRUB configuration.
	mkdir -p $TARGET_ROOT/boot/grub
	cat > $TARGET_ROOT/boot/grub/menu.lst << _EOF_
# /boot/grub/menu.lst: GRUB boot loader configuration.
#

# By default, boot the first entry.
default 0

# Boot automatically after 8 secs.
timeout 8

# Change the colors.
color yellow/brown light-green/black

# For booting SliTaz from : $TARGET_DEV
#
title 	SliTaz GNU/Linux (cooking) (Kernel $KERNEL)
		root $GRUB_ROOT
		kernel /boot/$KERNEL root=$TARGET_DEV

_EOF_
	# log
	echo "grub_config: $TARGET_ROOT/boot/grub/menu.lst" >>$LOG
	sleep 2
}

# Files install with gauge, calling for functions or with cmds.
install_files()
{
	(

	echo "XXX" && echo 10
	echo -e "\nCleaning the root partition if necessary..."
	echo "XXX"
	clean_target

	echo "XXX" && echo 20
	echo -e "\nInstalling the kernel ($KERNEL)..."
	echo "XXX"
	install_kernel

	echo "XXX" && echo 30
	echo -e "\nCopying the bootloader syslinux/isolinux..."
	echo "XXX"
	copy_bootloaders

	echo "XXX" && echo 40
	echo -e "\nCopying the compressed system (rootfs.gz)..."
	echo "XXX"
	cp /media/cdrom/boot/rootfs.gz $TARGET_ROOT
	sleep 2

	echo "XXX" && echo 50
	echo -e "\nExtracting the root system..."
	echo "XXX"
	extract_rootfs

	echo "XXX" && echo 60
	echo -e "\nCopying the default user files (/etc/skel)..."
	echo "XXX"
	gen_etc_skel
	sleep 2

	echo "XXX" && echo 70
	echo -e "\nPreconfiguring the system..."
	echo "XXX"
	pre_config_system

	echo "XXX" && echo 90
	echo -e "\nCreating the configuration file for GRUB (menu.lst)..."
	echo "XXX"
	grub_config

	echo "XXX" && echo 100
	echo -e "\nFinishing the files installation..."
	echo "XXX"
	echo "install_files: OK" >>$LOG
	sleep 4

	) |
	$DIALOG --title " Install files " \
		--backtitle "$BACKLIST" \
		--gauge "Starting to install files..." 18 70 0
}

# GRUB info with disk name used for grub-install.
grub_install()
{
	TARGET_DISK=`echo $TARGET_DEV | sed s/"[0-9]"/''/`
	set_messages
	$DIALOG --title " GRUB install " \
		--backtitle "$BACKLIST" \
		--clear --colors --yesno "$GRUB_INSTALL_MSG" 18 70
	retval=$?
	case $retval in
		0)
			(
			echo "XXX" && echo 50
			echo -e "\nRunning grub-install on : $TARGET_DISK..."
			echo "XXX"
			grub-install --no-floppy \
				--root-directory=$TARGET_ROOT $TARGET_DISK 2>>$LOG
			echo "XXX" && echo 100
			echo -e "\nFinished installation..."
			echo "XXX"
			sleep 2
			) |
			$DIALOG --title " GRUB install " \
				--backtitle "$BACKLIST" \
				--gauge "Installating GRUB..." 18 70 0 ;;
		1)
			echo "grub_install: NO" >>$LOG ;;
		255)
			echo -e "ESC pressed.\n" && exit 0 ;;
	esac
}

# Copy log file, umount target and eject cdrom.
umount_devices()
{
	(
	echo "XXX" && echo 25
	echo -e "\nCopying the log files ($LOG)..."
	echo "XXX"
	cp -a $LOG $TARGET_ROOT/var/log
	sleep 2
	echo "XXX" && echo 50
	echo -e "\nUnmounting the target ($TARGET_DEV)..."
	echo "XXX"
	if mount | grep -q $TARGET_ROOT; then
		umount $TARGET_ROOT 2>/dev/null
	fi
	echo "XXX" && echo 75
	echo -e "\nUnmounting and ejecting the cdrom..."
	echo "XXX"
	if mount | grep -q /media/cdrom; then
		umount /media/cdrom
		grep -q slitaz-loram-cdrom /etc/init.d/rcS || eject
	fi
	sleep 2
	echo "XXX" && echo 100
	echo -e "\n$TITLE..."
	echo "XXX"
	sleep 2
	) |
	$DIALOG --title " $TITLE " \
		--backtitle "$BACKLIST" \
		--gauge "$TITLE starting..." 18 70 0
}

# End of installation.
end_of_install()
{
	echo "end_of_install: `date`" >>$LOG
	$DIALOG --title " Installation complete " \
		--backtitle "$BACKLIST" \
		--yes-label "Exit" \
		--no-label "Reboot" \
		--clear --colors --yesno "$END_OF_INSTALL_MSG" 18 70
	retval=$?
	case $retval in
	0)
		TITLE="Exiting"
		umount_devices ;;
	1)
		TITLE="Rebooting"
		umount_devices
		reboot || reboot -f ;;
	255)
		echo -e "ESC pressed.\n" && exit 0 ;;
esac
}

#####################
# Upgrade functions #
#####################

# We need a partition to upgrade SliTaz.
ask_for_upgrade_dev()
{
	exec 3>&1
	UPGRADE_DEV=`$DIALOG --title " Target to upgrade " \
		--backtitle "$BACKLIST" --clear \
		--extra-label "List" --extra-button \
		--colors --inputbox "\n
The installer will upgrade the target by saving all configuration files and \
the list of installed packages. Then, it will clean the partition and install the \
version of SliTaz contained on the cdrom, restore the configuration files and \
reinstall all packages which are not present on the cdrom. You will need an active \
internet connection before upgrading.\n\n
\Z2Partition containing the system upgrade:\Zn" 18 70 2>&1 1>&3`
	retval=$?
	exec 3>&-
	check_retval
	# Display list and come back.
	if [ "$retval" = "3" ]; then
		fdisk_list
		ask_for_upgrade_dev
	fi
	# Empty value.
	if [ -z $UPGRADE_DEV ]; then
		ask_for_upgrade_dev
	fi
	# Check if specified device exists in /proc/partitions.
	DEV_NAME=${UPGRADE_DEV#/dev/}
	if cat /proc/partitions | grep -q $DEV_NAME; then
		echo "ask_for_target_dev: $TARGET_DEV" >>$LOG
	else
		ERROR_MSG="The partition \Z2$UPGRADE_DEV\Zn doesn't seem to exist."
		error_message
		ask_for_upgrade_dev
	fi
	echo "partition to upgrade: $UPGRADE_DEV" >>$LOG
}

# Prepare the partition to upgrade, backup, install, restore configs
# and reinstall pkgs.
upgrade_process()
{
	(
	echo "XXX" && echo 5
	echo -e "\nPreparing the target partition..."
	echo "XXX"
	# Mount point can be already used.
	if mount | grep -q $TARGET_ROOT; then
		umount $TARGET_ROOT 2>$LOG
	fi
	mkdir -p $TARGET_ROOT && sleep 2
	# Mount target.
	mount $UPGRADE_DEV $TARGET_ROOT >>$LOG 2>>$LOG
	cd $TARGET_ROOT
	TARGET_DEV=$UPGRADE_DEV
	set_messages

	echo "XXX" && echo 10
	echo -e "\nSearch for /etc/slitaz-release"
	echo "XXX"
	if [ -f etc/slitaz-release ]; then
		release=`cat etc/slitaz-release`
		echo "XXX" && echo 15
		echo -e "\nSliTaz release: $release"
		echo "XXX"
	else
		ERROR_MSG="The partition \Z2$UPGRADE_DEV\Zn doesn't appear to contain \
a SliTaz system, the file: /etc/slitaz-release doesn't exist."
		error_message
		exit 0
	fi && sleep 2

	echo "XXX" && echo 20
	echo -e "\nBackup /etc, /home and the packages list..."
	echo "XXX"
	# Backup target packages list.
	ls -1 var/lib/tazpkg/installed > home/packages-selection.list
	for dir in *
	do
		case "$dir" in
			boot)
				# Upgrade doesn't prompt for grub install, so backup and
				# create a new grub menu.lst.
				rm -rf $TARGET_ROOT/boot/vmlinuz-*
				mv $TARGET_ROOT/boot/grub/menu.lst \
					$TARGET_ROOT/boot/grub/menu.lst.bak 2>/dev/null
				grub_config ;;
			home)
				mv $TARGET_ROOT/home $TARGET_ROOT/home.bak
				echo "keeping /home found on: $UPGRADE_DEV" >>$LOG ;;
			etc)
				tar czf $TARGET_ROOT/etc.tar.gz etc
				mv $TARGET_ROOT/etc $TARGET_ROOT/etc.bak
				echo "keeping /etc found on: $UPGRADE_DEV" >>$LOG ;;
			var)
				if [ -d $TARGET_ROOT/var/www ]; then
					mv $TARGET_ROOT/var/www $TARGET_ROOT/www.bak
				fi
				rm -rf $TARGET_ROOT/var ;;
			lost+found)
				continue ;;
			*)
				echo "removing target: $dir" >>$LOG
				rm -rf $TARGET_ROOT/$dir 2>>$LOG ;;
		esac
	done
	if [ -d $TARGET_ROOT/mklost+found ]; then
		mklost+found 2>>$LOG
	fi
	sleep 2

	echo "XXX" && echo 25
	echo -e "\nInstalling the kernel ($KERNEL)..."
	echo "XXX"
	install_kernel

	echo "XXX" && echo 30
	echo -e "\nCopying the bootloader syslinux/isolinux..."
	echo "XXX"
	copy_bootloaders

	echo "XXX" && echo 35
	echo -e "\nCopying the compressed system (rootfs.gz)..."
	echo "XXX"
	cp /media/cdrom/boot/rootfs.gz $TARGET_ROOT
	sleep 2

	echo "XXX" && echo 40
	echo -e "\nExtracting the root system..."
	echo "XXX"
	extract_rootfs

	# Restore backups.
	echo "XXX" && echo 42
	echo -e "\nRestoring configuration files..."
	echo "XXX"
	rm -rf $TARGET_ROOT/home
	mv $TARGET_ROOT/home.bak $TARGET_ROOT/home
	rm -rf $TARGET_ROOT/etc
	mv $TARGET_ROOT/etc.bak $TARGET_ROOT/etc
	if [ -d $TARGET_ROOT/www.bak ]; then
		rm -rf $TARGET_ROOT/var/www
		mv $TARGET_ROOT/www.bak $TARGET_ROOT/var/www
	fi
	echo "backups restored: `date`" >> $LOG

	# /var/lib/slitaz-installer
	mkdir $TARGET_ROOT/var/lib/slitaz-installer
	mv $TARGET_ROOT/etc.tar.gz $TARGET_ROOT/var/lib/slitaz-installer
	mv $TARGET_ROOT/home/packages-selection.list $TARGET_ROOT/var/lib/slitaz-installer
	cd $TARGET_ROOT/var/lib/slitaz-installer

	# LiveCD packages list.
	echo "XXX" && echo 46
	echo -e "\nCreating package lists..."
	echo "XXX"
	ls -1 $TARGET_ROOT/var/lib/tazpkg/installed > packages-cdrom.list || exit 1
	echo "packages-cdrom.list: done" >> $LOG
	# Diff
	diff packages-cdrom.list packages-selection.list | \
		grep ^+[a-z] | sed s/^+// > packages-selection.diff
	echo "packages-selection.diff: done" >> $LOG
	# Get mirror list.
	tazpkg recharge >>$LOG 2>>$LOG
	if [ ! -f /var/lib/tazpkg/packages.list ]; then
		ERROR_MSG="The list of available packages on the mirror could not be \
downloaded. No missing packages will be reinstalled now, but \
you can do so later by looking at the following list: \n\n

/var/lib/slitaz-installer/packages-selection.diff"
		error_message
	fi
	sleep 2

	# Check if the pkg is on the mirror.
	echo "XXX" && echo 48
	echo -e "\nChecking the availability of packages..."
	echo "XXX"
	touch packages-to-install.list
	packages=0
	diff=`cat packages-selection.diff | sort`
	for pkg in $diff
	do
		if grep -q ^$pkg-[0-9] /var/lib/tazpkg/packages.list; then
			packages=$(($packages+1))
			echo "$pkg" >> packages-to-install.list
		fi
	done

	# Calculate the percent for one package and install.
	echo "XXX" && echo 50
	echo -e "\nInstalling any packages..."
	echo "XXX"
	sleep 2
	if [ "$packages" == "0" ]; then
		echo "packages to install: 0" >> $LOG
	else
		onepkg=$((48/$packages))
		pct=50
		# Get-install all missing pkgs.
		for pkg in `cat packages-to-install.list`
		do
			pct=$(($pct+$onepkg))
			echo "XXX" && echo $pct
			echo -e "\nInstallation of: $pkg..."
			echo "XXX"
			# Log please.
			echo "get-install: $pkg" >>$LOG
			# Get install package and answer yes in case of dependencies.
			pkgname=`grep ^$pkg /var/lib/tazpkg/packages.list`
			tazpkg get $pkg >/dev/null 2>/dev/null
			yes "" | tazpkg install $pkgname.tazpkg --root=$TARGET_ROOT >/dev/null 2>/dev/null
			rm -f $pkgname.tazpkg
		done
	fi
	echo "XXX" && echo 100
	echo -e "\nInstallation of packages complete..."
	echo "XXX"
	sleep 2
	) |
	$DIALOG --title " Processing system upgrade " \
		--backtitle "$BACKLIST" \
		--gauge "Target in preparation..." 18 70 0
}

# End of system upgrade.
end_of_upgrade()
{
	TARGET_DEV=$UPGRADE_DEV
	set_messages
	pkgscd=`cat $TARGET_ROOT/var/lib/slitaz-installer/packages-cdrom.list | wc -l`
	pkginst=`cat $TARGET_ROOT/var/lib/slitaz-installer/packages-to-install.list | wc -l`
	echo "end_of_upgrade: `date`" >>$LOG
	$DIALOG --title " Upgrade completed " \
		--backtitle "$BACKLIST" \
		--yes-label "Exit" \
		--no-label "Reboot" \
		--clear --colors --yesno "\n
Upgrade finished. You can know restart (reboot) \
from your SliTaz GNU/Linux system.\n\n
Packages on the cdrom      : $pkgscd\n
Packages installed from the mirror : $pkginst\n" 18 70
	retval=$?
	case $retval in
	0)
		TITLE="Exiting"
		umount_devices ;;
	1)
		TITLE="Rebooting"
		umount_devices
		reboot || reboot -f ;;
	255)
		echo -e "ESC pressed.\n" && exit 0 ;;
esac
}

######################
# Installer sequence #
######################

set_messages
check_root
start_installer

case $ACTION in
	upgrade)
		BACKLIST="$BACKLIST (Upgrade)"
		mount_cdrom
		ask_for_upgrade_dev
		upgrade_process
		end_of_upgrade
		;;
	install|*)
		mount_cdrom
		ask_for_target_dev
		ask_for_mkfs_target_dev
		prepare_target_dev
		ask_for_hostname
		install_files
		grub_install
		end_of_install
		;;
esac

exit 0
