#!/bin/sh

ANSWER="/tmp/.setup"
TITLE="Arch Linux Installation"
# use the first VT not dedicated to a running console
LOG="/dev/tty7"
# don't use /mnt because it's intended to mount other things there!
DESTDIR="/tmp/install"
EDITOR=

# name of the kernel image
VMLINUZ="vmlinuz26"

# abstract the common pacman args
PACMAN="pacman --root ${DESTDIR} --config /tmp/pacman.conf --noconfirm"
# downloader
DLPROG="wget"
# sources
SYNC_URL=
FILE_URL="file:///src/core-$(uname -m)/pkg"
MIRRORLIST="/etc/pacman.d/mirrorlist"

# partitions
PART_ROOT=
PART_SWAP=

PATH=$PATH:/tmp/bin:/tmp/usr/bin:/tmp/sbin:/tmp/usr/sbin

# default filesystem specs (the + is bootable flag)
# <mountpoint>:<partsize>:<fstype>[:+]
DEFAULTFS="/boot:32:ext2:+ swap:256:swap /:7500:ext3 /home:*:ext3"

# install stages
S_SRC=0         # choose install medium
S_NET=0         # network configuration
S_CLOCK=0       # clock and timezone
S_PART=0        # partitioning
S_MKFS=0        # formatting
S_MKFSAUTO=0    # auto fs part/formatting TODO: kill this
S_SELECT=0      # package selection
S_INSTALL=0     # package installation
S_CONFIG=0      # configuration editing
S_LILO=0        # TODO: kill this - if using lilo 
S_GRUB=0        # TODO: kill this - if using grub
S_BOOT=""       # bootloader installed (set to loader name instead of 1)

# menu item tracker- autoselect the next item
NEXTITEM=""

# DIALOG()
# an el-cheapo dialog wrapper
#
# parameters: see dialog(1)
# returns: whatever dialog did
DIALOG() {
	dialog --backtitle "$TITLE" --aspect 15 "$@"
	return $?
}

finddisks() {
	workdir="$PWD"
	cd /sys/block
	# ide devices
	for dev in $(ls | egrep '^hd'); do
		if [ "$(cat $dev/device/media)" = "disk" ]; then
			if [ "$(dmesg | grep sectors | grep $dev)" ]; then
				echo "/dev/$dev"
				[ "$1" ] && echo $1
			fi
		fi
	done
	#scsi/sata devices
	for dev in $(ls | egrep '^sd'); do
		if ! [ "$(cat $dev/device/type)" = "5" ]; then
			if [ "$(dmesg | grep sectors | grep $dev)" ]; then
				echo "/dev/$dev"
				[ "$1" ] && echo $1
			fi
		fi
	done
	# cciss controllers
	if [ -d /dev/cciss ] ; then
		cd /dev/cciss
		for dev in $(ls | egrep -v 'p'); do
			echo "/dev/cciss/$dev"
			[ "$1" ] && echo $1
		done
	fi
	# Smart 2 controllers
        if [ -d /dev/ida ] ; then
                cd /dev/ida
                for dev in $(ls | egrep -v 'p'); do
                        echo "/dev/ida/$dev"
                        [ "$1" ] && echo $1
                done
        fi
	cd "$workdir"
}

# getuuid()
# converts /dev/[hs]d?[0-9] devices to UUIDs
#
# parameters: device file
# outputs:    UUID on success
#             nothing on failure
# returns:    nothing
getuuid()
{
    if [ "${1%%/[hs]d?[0-9]}" != "${1}" ]; then
        echo "$(blkid -s UUID -o value ${1})"
    fi
}


findcdroms() {
	workdir="$PWD"
	cd /sys/block
	# ide devices
	for dev in $(ls | egrep '^hd'); do
		if [ "$(cat $dev/device/media)" = "cdrom" ]; then
			echo "/dev/$dev"
			[ "$1" ] && echo $1
		fi
	done
	# scsi/sata and other devices
	for dev in $(ls | egrep '^sd|^sr|^scd|^sg'); do
		if [ "$(cat $dev/device/type)" = "5" ]; then
			echo "/dev/$dev"
			[ "$1" ] && echo $1
		fi
	done
	cd "$workdir"
}

findpartitions() {
	workdir="$PWD"
	for devpath in $(finddisks); do
		disk=$(echo $devpath | sed 's|.*/||')
		cd /sys/block/$disk
		for part in $disk*; do
			# check if not already assembled to a raid device
			if ! [ "$(cat /proc/mdstat 2>/dev/null | grep $part)" -o "$(fstype 2>/dev/null </dev/$part | grep "lvm2")" -o "$(sfdisk -c /dev/$disk $(echo $part | sed -e "s#$disk##g") 2>/dev/null | grep "5")" ]; then
				if [ -d $part ]; then
					echo "/dev/$part"
					[ "$1" ] && echo $1
				fi
			fi
		done
	done
	# include any mapped devices
	for devpath in $(ls /dev/mapper 2>/dev/null | grep -v control); do
		echo "/dev/mapper/$devpath"
		[ "$1" ] && echo $1
	done
	# include any raid md devices
	for devpath in $(ls -d /dev/md* | grep '[0-9]' 2>/dev/null); do
		if cat /proc/mdstat | grep -qw $(echo $devpath | sed -e 's|/dev/||g'); then
		echo "$devpath"
		[ "$1" ] && echo $1
		fi
	done
	# inlcude cciss controllers
	if [ -d /dev/cciss ] ; then
		cd /dev/cciss
		for dev in $(ls | egrep 'p'); do
			echo "/dev/cciss/$dev"
			[ "$1" ] && echo $1
		done
	fi
	# inlcude Smart 2 controllers
	if [ -d /dev/ida ] ; then
		cd /dev/ida
		for dev in $(ls | egrep 'p'); do
			echo "/dev/ida/$dev"
			[ "$1" ] && echo $1
		done
	fi
	cd "$workdir"
}

get_grub_map() {
	rm /tmp/dev.map
	DIALOG --infobox "Generating GRUB device map...\nThis could take a while.\n\n Please be patient." 0 0
	$DESTDIR/sbin/grub --no-floppy --device-map /tmp/dev.map >/tmp/grub.log 2>&1 <<EOF
quit
EOF
}

mapdev() {
	partition_flag=0
	device_found=0
	devs=$(cat /tmp/dev.map | grep -v fd | sed 's/ *\t/ /' | sed ':a;$!N;$!ba;s/\n/ /g')
	linuxdevice=$(echo $1 | cut -b1-8)
	if [ "$(echo $1 | egrep '[0-9]$')" ]; then
		# /dev/hdXY
		pnum=$(echo $1 | cut -b9-)
		pnum=$(($pnum-1))
		partition_flag=1
	fi
	for  dev in $devs
	do
	    if [ "(" = $(echo $dev | cut -b1) ]; then
		grubdevice="$dev"
	    else
		if [ "$dev" = "$linuxdevice" ]; then
			device_found=1
			break   
		fi
	   fi
	done	
	if [ "$device_found" = "1" ]; then
		if [ "$partition_flag" = "0" ]; then
			echo "$grubdevice"
		else
			grubdevice_stringlen=${#grubdevice}
			grubdevice_stringlen=$(($grubdevice_stringlen - 1))
			grubdevice=$(echo $grubdevice | cut -b1-$grubdevice_stringlen)
			echo "$grubdevice,$pnum)"
		fi
	else
		echo " DEVICE NOT FOUND"
	fi
}

printk()
{
	case $1 in
		"on")  echo 4 >/proc/sys/kernel/printk ;;
		"off") echo 0 >/proc/sys/kernel/printk ;;
	esac
}

getdest() {
	[ "$DESTDIR" ] && return 0
	DIALOG --inputbox "Enter the destination directory where your target system is mounted" 8 65 "/tmp/install" 2>$ANSWER || return 1
	DESTDIR=$(cat $ANSWER)
}

geteditor() {
	if ! [ $(which vi) ]; then
		DIALOG --menu "Select a Text Editor to Use" 10 35 3 \
			"1" "nano (easier)" 2>$ANSWER
	else
		DIALOG --menu "Select a Text Editor to Use" 10 35 3 \
			"1" "nano (easier)" \
			"2" "vi" 2>$ANSWER
	fi
	case $(cat $ANSWER) in
		"1") EDITOR="nano" ;;
		"2") EDITOR="vi" ;;
		*)   EDITOR="nano" ;;
	esac 
}

_mkfs() {
	local _domk=$1
	local _device=$2
	local _fstype=$3
	local _dest=$4
	local _mountpoint=$5

	if [ "${_fstype}" = "swap" ]; then
		_mountpoint="swap"
		swapoff ${_device} >/dev/null 2>&1
		if [ "${_domk}" = "yes" ]; then
			mkswap ${_device} >$LOG 2>&1
			if [ $? != 0 ]; then
				DIALOG --msgbox "Error creating swap: mkswap ${_device}" 0 0
				return 1
			fi
		fi
		swapon ${_device} >$LOG 2>&1
		if [ $? != 0 ]; then
			DIALOG --msgbox "Error activating swap: swapon ${_device}" 0 0
			return 1
		fi
	elif [ "${_fstype}" = "xfs" ]; then
		if [ "${_domk}" = "yes" ]; then
			mkfs.xfs -f ${_device} >$LOG 2>&1
			if [ $? != 0 ]; then
				DIALOG --msgbox "Error creating filesystem: mkfs.xfs ${_device}" 0 0
				return 1
			fi
			sleep 2
		fi
		mkdir -p ${_dest}${_mountpoint}
		mount -t xfs ${_device} ${_dest}${_mountpoint} >$LOG 2>&1
		if [ $? != 0 ]; then
			DIALOG --msgbox "Error mounting ${_dest}${_mountpoint}" 0 0
			return 1
		fi
	elif [ "${_fstype}" = "jfs" ]; then
		if [ "${_domk}" = "yes" ]; then
			yes | mkfs.jfs ${_device} >$LOG 2>&1
			if [ $? != 0 ]; then
				DIALOG --msgbox "Error creating filesystem: mkfs.jfs ${_device}" 0 0
				return 1
			fi
			sleep 2
		fi
		mkdir -p ${_dest}${_mountpoint}
		mount -t jfs ${_device} ${_dest}${_mountpoint} >$LOG 2>&1
		if [ $? != 0 ]; then
			DIALOG --msgbox "Error mounting ${_dest}${_mountpoint}" 0 0
			return 1
		fi
	elif [ "${_fstype}" = "reiserfs" ]; then
		if [ "${_domk}" = "yes" ]; then
			yes | mkreiserfs ${_device} >$LOG 2>&1
			if [ $? != 0 ]; then
				DIALOG --msgbox "Error creating filesystem: mkreiserfs ${_device}" 0 0
				return 1
			fi
			sleep 2
		fi
		mkdir -p ${_dest}${_mountpoint}
		mount -t reiserfs ${_device} ${_dest}${_mountpoint} >$LOG 2>&1
		if [ $? != 0 ]; then
			DIALOG --msgbox "Error mounting ${_dest}${_mountpoint}" 0 0
			return 1
		fi
	elif [ "${_fstype}" = "ext2" ]; then
		if [ "${_domk}" = "yes" ]; then
			mke2fs "${_device}" >$LOG 2>&1
			if [ $? != 0 ]; then
				DIALOG --msgbox "Error creating filesystem: mke2fs ${_device}" 0 0
				return 1
			fi
			sleep 2
		fi
		mkdir -p ${_dest}${_mountpoint}
		mount -t ext2 ${_device} ${_dest}${_mountpoint} >$LOG 2>&1
		if [ $? != 0 ]; then
			DIALOG --msgbox "Error mounting ${_dest}${_mountpoint}" 0 0
			return 1
		fi
	elif [ "${_fstype}" = "ext3" ]; then
		if [ "${_domk}" = "yes" ]; then
			mke2fs -j ${_device} >$LOG 2>&1
			if [ $? != 0 ]; then
				DIALOG --msgbox "Error creating filesystem: mke2fs -j ${_device}" 0 0
				return 1
			fi
			sleep 2
		fi
		mkdir -p ${_dest}${_mountpoint}
		mount -t ext3 ${_device} ${_dest}${_mountpoint} >$LOG 2>&1
		if [ $? != 0 ]; then
			DIALOG --msgbox "Error mounting ${_dest}${_mountpoint}" 0 0
			return 1
		fi
	elif [ "${_fstype}" = "vfat" ]; then
		if [ "${_domk}" = "yes" ]; then
			mkfs.vfat ${_device} >$LOG 2>&1
			if [ $? != 0 ]; then
				DIALOG --msgbox "Error creating filesystem: mkfs.vfat ${_device}" 0 0
				return 1
			fi
			sleep 2
		fi
		mkdir -p ${_dest}${_mountpoint}
		mount -t vfat ${_device} ${_dest}${_mountpoint} >$LOG 2>&1
		if [ $? != 0 ]; then
			DIALOG --msgbox "Error mounting ${_dest}${_mountpoint}" 0 0
			return 1
		fi
	else
		DIALOG --msgbox "unknown fstype for ${_device}" 0 0
		return 1
	fi

	# add to temp fstab
	if [ "$UUIDPARAMETER" = "yes" ]; then
		local _uuid="$(getuuid ${_device})"
		if [ -n "${_uuid}" ]; then
			_device="UUID=${_uuid}"
		fi
		echo -n "${_device} ${_mountpoint} ${_fstype} defaults 0 " >>/tmp/.fstab
	else
		echo -n "${_device} ${_mountpoint} ${_fstype} defaults 0 " >>/tmp/.fstab
	fi
	if [ "${_fstype}" = "swap" ]; then
		echo "0" >>/tmp/.fstab
	else
		echo "1" >>/tmp/.fstab
	fi
}

mksimplefs() {
	DEVICE=$1
	FSSPECS=$2
	sfdisk_input=""

	# we assume a /dev/hdX format (or /dev/sdX)
	dev=$DEVICE
	PART_SWAP="${dev}2"
	PART_ROOT="${dev}3"

	if [ "$S_MKFS" = "1" ]; then
		DIALOG --msgbox "You have already prepared your filesystems manually" 0 0
		return 0
	fi

	# validate DEVICE
	if [ ! -b "$DEVICE" ]; then
	  DIALOG --msgbox "Device '$DEVICE' is not valid" 0 0
	  return 1
	fi

	# validate DEST
	if [ ! -d "$DESTDIR" ]; then
		DIALOG --msgbox "Destination directory '$DESTDIR' is not valid" 0 0
		return 1
	fi

	# /boot required
	if [ $(echo $FSSPECS | grep '/boot:' | wc -l) -ne 1 ]; then
		DIALOG --msgbox "Need exactly one boot partition" 0 0
		return 1
	fi

	# swap required
	if [ $(echo $FSSPECS | grep 'swap:' | wc -l) -lt 1 ]; then
		DIALOG --msgbox "Need at least one swap partition" 0 0
		return 1
	fi

	# / required
	if [ $(echo $FSSPECS | grep '/:' | wc -l) -ne 1 ]; then
		DIALOG --msgbox "Need exactly one root partition" 0 0
		return 1
	fi

	if [ $(echo $FSSPECS | grep '/home:' | wc -l) -ne 1 ]; then
		DIALOG --msgbox "Need exactly one home partition" 0 0
		return 1
	fi

	rm -f /tmp/.fstab

	# disable swap and all mounted partitions, umount / last!
	DIALOG --infobox "Disabling swapspace, unmounting already mounted disk devices..." 0 0
	swapoff -a >/dev/null 2>&1
	umount $(mount | grep -v "${DESTDIR} " | grep "${DESTDIR}" | sed 's|\ .*||g') >/dev/null 2>&1
	umount $(mount | grep "${DESTDIR} " | sed 's|\ .*||g') >/dev/null 2>&1

	# setup input var for sfdisk
	for fsspec in $FSSPECS; do
		fssize=$(echo $fsspec | tr -d ' ' | cut -f2 -d:)
		if [ "$fssize" = "*" ]; then
				fssize_spec=';'
		else
				fssize_spec=",$fssize"
		fi
		fstype=$(echo $fsspec | tr -d ' ' | cut -f3 -d:)
		if [ "$fstype" = "swap" ]; then
				fstype_spec=",S"
		else
				fstype_spec=","
		fi
		bootflag=$(echo $fsspec | tr -d ' ' | cut -f4 -d:)
		if [ "$bootflag" = "+" ]; then
			bootflag_spec=",*"
		else
			bootflag_spec=""
		fi
		sfdisk_input="${sfdisk_input}${fssize_spec}${fstype_spec}${bootflag_spec}\n"
	done
	sfdisk_input=$(printf "$sfdisk_input")

	# invoke sfdisk
	printk off
	DIALOG --infobox "Partitioning $DEVICE" 0 0
	sfdisk $DEVICE -uM >$LOG 2>&1 <<EOF
$sfdisk_input
EOF
	if [ $? -gt 0 ]; then
		DIALOG --msgbox "Error partitioning $DEVICE (see $LOG for details)" 0 0
		prink on
		return 1
	fi
	printk on

	# need to mount root first, then do it again for the others
	part=1
	for fsspec in $FSSPECS; do
		mountpoint=$(echo $fsspec | tr -d ' ' | cut -f1 -d:)
		fstype=$(echo $fsspec | tr -d ' ' | cut -f3 -d:)
		if echo $mountpoint | tr -d ' ' | grep '^/$' 2>&1 > /dev/null; then
				_mkfs yes ${DEVICE}${part} "$fstype" "$DESTDIR" "$mountpoint" || return 1
		fi
		part=$(($part + 1))
	done

	# make other filesystems
	part=1
	for fsspec in $FSSPECS; do
		mountpoint=$(echo $fsspec | tr -d ' ' | cut -f1 -d:)
		fstype=$(echo $fsspec | tr -d ' ' | cut -f3 -d:)
		if [ $(echo $mountpoint | tr -d ' ' | grep '^/$' | wc -l) -eq 0 ]; then
			_mkfs yes ${DEVICE}${part} "$fstype" "$DESTDIR" "$mountpoint" || return 1
		fi
		part=$(($part + 1))
	done

	DIALOG --msgbox "Auto-prepare was successful" 0 0
	S_MKFSAUTO=1
}

partition() {
	if [ "$S_MKFSAUTO" = "1" ]; then
		DIALOG --msgbox "You have already prepared your filesystems with Auto-prepare" 0 0
		return 0
	fi
	# disable swap and all mounted partitions, umount / last!
	DIALOG --infobox "Disabling swapspace, unmounting already mounted disk devices..." 0 0
	swapoff -a >/dev/null 2>&1
	umount $(mount | grep -v "${DESTDIR} " | grep "${DESTDIR}" | sed 's|\ .*||g') >/dev/null 2>&1
	umount $(mount | grep "${DESTDIR} " | sed 's|\ .*||g') >/dev/null 2>&1
	#
	# Select disk to partition
	#
	DISCS=$(finddisks _)
	DISCS="$DISCS OTHER -"
	DIALOG --msgbox "Available Disks:\n\n$(for i in $(finddisks); do echo -n $(echo $i | sed 's#/dev/##g'): '' ; dmesg | grep $(echo $i | sed 's#/dev/##g') | grep sectors | sort -u | cut -d'(' -f2 | cut -d')' -f1; echo "\n"; done)\n"
	DIALOG --menu "Select the disk you want to partition" 14 55 7 $DISCS 2>$ANSWER || return 1
	DISC=$(cat $ANSWER)
	if [ "$DISC" = "OTHER" ]; then
		DIALOG --inputbox "Enter the full path to the device you wish to partition" 8 65 "/dev/sda" 2>$ANSWER || return 1
		DISC=$(cat $ANSWER)
	fi
	while [ "$DISC" != "DONE" ]; do
		#
		# Partition disc
		#
		DIALOG --msgbox "Now you'll be put into the cfdisk program where you can partition your hard drive. You should make a swap partition and as many data partitions as you will need.  NOTE: cfdisk may tell you to reboot after creating partitions.  If you need to reboot, just re-enter this install program, skip this step and go on to step 2." 18 70
		cfdisk $DISC

		DIALOG --menu "Select the disk you want to partition" 14 55 7 $DISCS DONE + 2>$ANSWER || return 1
		DISC=$(cat $ANSWER)
		if [ "$DISC" = "OTHER" ]; then
			DIALOG --inputbox "Enter the full path to the device you wish to partition" 8 65 "/dev/sda" 2>$ANSWER || return 1
			DISC=$(cat $ANSWER)
		fi
	done
	S_PART=1
}

mountpoints() {
	if [ "$S_MKFSAUTO" = "1" ]; then
		DIALOG --msgbox "You have already prepared your filesystems with Auto-prepare" 0 0
		return 0
	fi
	while [ "$PARTFINISH" != "DONE" ]; do
	: >/tmp/.fstab
	: >/tmp/.parts

	# Determine which filesystems are available
	insmod /lib/modules/$(uname -r)/kernel/fs/xfs/xfs.ko >/dev/null 2>&1
	insmod /lib/modules/$(uname -r)/kernel/fs/jfs/jfs.ko >/dev/null 2>&1
	FSOPTS="ext2 Ext2 ext3 Ext3"
	[ "$(which mkreiserfs 2>/dev/null)" ] && FSOPTS="$FSOPTS reiserfs Reiser3"
	[ "$(which mkfs.xfs 2>/dev/null)" ]   && FSOPTS="$FSOPTS xfs XFS"
	[ "$(which mkfs.jfs 2>/dev/null)" ]   && FSOPTS="$FSOPTS jfs JFS"
	[ "$(which mkfs.vfat 2>/dev/null)" ]   && FSOPTS="$FSOPTS vfat VFAT"

	#
	# Select mountpoints
	#
	DIALOG --msgbox "Available Disks:\n\n$(for i in $(finddisks); do echo -n $(echo $i | sed 's#/dev/##g'): '' ; dmesg | grep $(echo $i | sed 's#/dev/##g') | grep sectors | sort -u | cut -d'(' -f2 | cut -d')' -f1; echo "\n"; done)\n" 0 0
	PARTS=$(findpartitions _)
	DIALOG --menu "Select the partition to use as swap" 21 50 13 NONE - $PARTS 2>$ANSWER || return 1
	PART=$(cat $ANSWER)
	PARTS="$(echo $PARTS | sed -e "s#${PART}\ _##g")"
	PART_SWAP=$PART
	if [ "$PART_SWAP" != "NONE" ]; then
		DOMKFS="no"
		DIALOG --yesno "Would you like to create a filesystem on $PART?\n\n(This will overwrite existing data!)" 0 0 && DOMKFS="yes"
		echo "$PART:swap:swap:$DOMKFS" >>/tmp/.parts
	fi
	
	DIALOG --menu "Select the partition to mount as /" 21 50 13 $PARTS 2>$ANSWER || return 1
	PART=$(cat $ANSWER)
	PARTS="$(echo $PARTS | sed -e "s#${PART}\ _##g")"
	PART_ROOT=$PART
	# Select root filesystem type
	DIALOG --menu "Select a filesystem for $PART" 13 45 6 $FSOPTS 2>$ANSWER || return 1
	FSTYPE=$(cat $ANSWER)
	DOMKFS="no"
	DIALOG --yesno "Would you like to create a filesystem on $PART?\n\n(This will overwrite existing data!)" 0 0 && DOMKFS="yes"
	echo "$PART:$FSTYPE:/:$DOMKFS" >>/tmp/.parts

	#
	# Additional partitions
	#
	DIALOG --menu "Select any additional partitions to mount under your new root (select DONE when finished)" 21 50 13 $PARTS DONE _ 2>$ANSWER || return 1
	PART=$(cat $ANSWER)
	while [ "$PART" != "DONE" ]; do
		PARTS="$(echo $PARTS | sed -e "s#${PART}\ _##g")"
		# Select a filesystem type
		DIALOG --menu "Select a filesystem for $PART" 13 45 6 $FSOPTS 2>$ANSWER || return 1
		FSTYPE=$(cat $ANSWER)
		MP=""
		while [ "${MP}" = "" ]; do
			DIALOG --inputbox "Enter the mountpoint for $PART" 8 65 "/boot" 2>$ANSWER || return 1
			MP=$(cat $ANSWER)
			if grep ":$MP:" /tmp/.parts; then
				DIALOG --msgbox "ERROR: You have defined 2 identical mountpoints! Please select another mountpoint." 8 65
				MP=""
			fi
		done
		DOMKFS="no"
		DIALOG --yesno "Would you like to create a filesystem on $PART?\n\n(This will overwrite existing data!)" 0 0 && DOMKFS="yes"
		echo "$PART:$FSTYPE:$MP:$DOMKFS" >>/tmp/.parts
		DIALOG --menu "Select any additional partitions to mount under your new root" 21 50 13 $PARTS DONE _ 2>$ANSWER || return 1
		PART=$(cat $ANSWER)
	done
	DIALOG --yesno "Would you like to create and mount the filesytems like this?\n\nSyntax\n------\nDEVICE:TYPE:MOUNTPOINT:FORMAT\n\n$(for i in $(cat /tmp/.parts); do echo "$i\n";done)" 0 0 && PARTFINISH="DONE"
	done
	# disable swap and all mounted partitions
	DIALOG --infobox "Disabling swapspace, unmounting already mounted disk devices..." 0 0
	swapoff -a >/dev/null 2>&1
	umount $(mount | grep -v "${DESTDIR} " | grep "${DESTDIR}" | sed 's|\ .*||g') >/dev/null 2>&1
	umount $(mount | grep "${DESTDIR} " | sed 's|\ .*||g') >/dev/null 2>&1
	for line in $(cat /tmp/.parts); do
		PART=$(echo $line | cut -d: -f 1)
		FSTYPE=$(echo $line | cut -d: -f 2)
		MP=$(echo $line | cut -d: -f 3)
		DOMKFS=$(echo $line | cut -d: -f 4)
		umount ${DESTDIR}${MP}
		if [ "$DOMKFS" = "yes" ]; then
			if [ "$FSTYPE" = "swap" ]; then
				DIALOG --infobox "Creating swapspace on $PART, activating..." 0 0
			else
				DIALOG --infobox "Creating $FSTYPE on $PART, mounting to ${DESTDIR}${MP}" 0 0
			fi
			_mkfs yes $PART $FSTYPE $DESTDIR $MP || return 1
		else
			if [ "$FSTYPE" = "swap" ]; then
				DIALOG --infobox "Activating swapspace on $PART" 0 0
			else
				DIALOG --infobox "Mounting $PART to ${DESTDIR}${MP}"
			fi
			_mkfs no $PART $FSTYPE $DESTDIR $MP || return 1
		fi
		sleep 1
	done

	DIALOG --msgbox "Partitions were successfully mounted." 0 0
	S_MKFS=1
}

getsource() {
	S_SRC=0
	if [ "$MODE" = "cd" ]; then
		DIALOG --menu "You can either install packages from an Arch Linux CD, or you can switch to another VC and manually mount the source media under /src.  If you manually mount to /src, make sure the packages are available under /src/core-$(uname -m)/pkg.\n\n" \
			15 55 2 \
			"CD" "Mount the CD-ROM and install from there" \
			"SRC" "I have manually mounted the source media" 2>$ANSWER || return 1
		case $(cat $ANSWER) in
			"CD")
				select_cdrom
				;;
			"SRC")
				;;
		esac
		if [ ! -d /src/core-$(uname -m)/pkg ]; then
			DIALOG --msgbox "Package directory /src/core-$(uname -m)/pkg is missing!" 0 0
			return 1
		fi
	fi

	if [ "$MODE" = "ftp" ]; then
		select_mirror
	fi
	S_SRC=1
}

# select_mirror()
# Prompt user for preferred mirror and set $SYNC_URL
#
# args: none
# returns: nothing
select_mirror() {
	DIALOG --msgbox "Keep in mind ftp.archlinux.org is throttled.\nPlease select another mirror to get full download speed." 18 70
	# FIXME: this regex doesn't honor commenting
	MIRRORS=$(egrep -o '((ftp)|(http))://[^/]*' "${MIRRORLIST}" | sed 's|$| _|g')
	DIALOG --menu "Select an FTP/HTTP mirror" 14 55 7 \
		$MIRRORS \
		"Custom" "_" 2>$ANSWER || return 1
	local _server=$(cat $ANSWER)
	if [ "${_server}" = "Custom" ]; then
		DIALOG --inputbox "Enter the full URL to core repo." 8 65 \
			"ftp://ftp.archlinux.org/core/os/i686" 2>$ANSWER || return 1
			SYNC_URL=$(cat $ANSWER)
	else
		SYNC_URL=$(egrep -o "${_server}.*" "${MIRRORLIST}" | sed "s#\$repo/os/x86_64#core/os/$(uname -m)#g")
	fi
}

select_cdrom () {
	# we may have leftover mounts...
	umount /src >/dev/null 2>&1
	CDROMS=$(findcdroms _)
	if [ "$CDROMS" = "" ]; then
		DIALOG --msgbox "No CD drives were found" 0 0
		return 1
	fi
	DIALOG --msgbox "Available CD drives:\n\n$(for i in $(findcdroms); do k=$(echo $i: | sed 's#/dev/##g'); dmesg | grep $k | grep "CD/"| cut -d, -f1 | sed 's/ /|/g';l=$(echo "$k"$(dmesg | grep $(dmesg | grep $(echo $k | sed 's#:##g') |grep CD- |cut -d\  -f2) | grep ^scsi | sed -e 's/ /|/g' | sed -e 's#.*CD-ROM##g' | sed -e 's#|||##g' | sed -e 's#||#|#g')); ! [ "$l" = "$k" ] && echo $l; done)\n" 0 0
	DIALOG --menu "Select the CD drive that contains Arch packages" 14 55 7 $CDROMS 2>$ANSWER || return 1
	CDROM=$(cat $ANSWER)
	DIALOG --infobox "Mounting $CDROM" 0 0
	mount -t iso9660 $CDROM /src >/dev/null 2>&1
	if [ $? -gt 0 ]; then
		DIALOG --msgbox "Failed to mount $CDROM" 0 0
		return 1
	fi
}

prepare_pacman() {
	cd /tmp
	if [ "$MODE" = "cd" ]; then
		local serverurl="${FILE_URL}"
	elif [ "$MODE" = "ftp" ]; then
		local serverurl="${SYNC_URL}"
	fi
	# Setup a pacman.conf in /tmp
	cat << EOF > /tmp/pacman.conf
[options]
CacheDir = ${DESTDIR}/var/cache/pacman/pkg
CacheDir = /src/core-$(uname -m)/pkg

[core]
Server = ${serverurl}
EOF

	# Set up the necessary directories for pacman use
	[ ! -d "${DESTDIR}/var/cache/pacman/pkg" ] && mkdir -m 755 -p "${DESTDIR}/var/cache/pacman/pkg"
	[ ! -d "${DESTDIR}/var/lib/pacman" ] && mkdir -m 755 -p "${DESTDIR}/var/lib/pacman"

	DIALOG --infobox "Refreshing package database..." 6 45
	# FIXME: if sync fails. this function needs to fail.
	$PACMAN -Sy >$LOG 2>&1
}

selectpkg() {
	if ! [ "$S_SRC" = "1" ]; then
		DIALOG --msgbox "Error:\nYou must select Source first." 0 0
		return 1
	fi
	# Archboot setup CD Mode uses packages.txt!
	if [ "$MODE" = "cd" ]; then
		DIALOG --msgbox "Package selection is split into two stages.  First you will select package categories that contain packages you may be interested in.  Then you will be presented with a full list of packages in your selected categories, allowing you to fine-tune your selection.\n\nNOTE: It is recommended that you install the BASE category from this setup, SUPPORT contains additional useful packages for networking and filesystems, DEVEL contains software building tools." 18 70
		# set up our install location if necessary and sync up
		# so we can get package lists
		prepare_pacman 
		PKGS="/src/core-$(uname -m)/pkg/packages.txt"
		if ! [ -f /tmp/.pkgcategory ]; then
			CHKLIST="base ^ ON"
			for category in $(cat $PKGS | sed 's|/.*$||g' | uniq | grep -v base | grep -v kernels); do
				CHKLIST="$CHKLIST $category - OFF"
			done
		else
			CHKLIST=
			for i in $(cat /tmp/.pkgcategory | sed 's|\"||g'); do
				CHKLIST="$CHKLIST $i ^ ON"
			done
			for category in $(cat $PKGS | sed 's|/.*$||g' | uniq | grep -v kernels); do
				grep $category /tmp/.pkgcategory > /dev/null 2>&1 || CHKLIST="$CHKLIST $category - OFF"
			done
		fi
		DIALOG --checklist "Select Package Categories" 19 55 12 $CHKLIST 2>/tmp/.pkgcategory || return 1
		SELECTALL="no"
		DIALOG --yesno "Select all packages by default?" 0 0 && SELECTALL="yes"
		CHKLIST=
		for category in $(cat /tmp/.pkgcategory | sed 's|"||g'); do
			if [ "$category" = "x11-drivers" ]; then
				DIALOG --msgbox "NOTE:\n-------\nxf86-video-via and xf86-video-unichrome are disabled by default, please select the correct package you need and don't choose both! Else installation will fail!" 0 0
			fi
			tag="OFF"
			if [ "$SELECTALL" = "yes" ]; then
				tag="ON"
			fi
			list=$(cat $PKGS | grep "$category/" | grep -v 'xf86-video-unichrome' | grep -v 'xf86-video-via' | sed 's|^[a-z0-9-]*/||g' | sed "s|.pkg.tar.gz$| ($category) $tag|g" | sort)
			CHKLIST="$CHKLIST $list"
			tag="OFF"
			list=$(cat $PKGS | grep "$category/" | grep 'xf86-video-unichrome' | sed 's|^[a-z0-9-]*/||g' | sed "s|.pkg.tar.gz$| ($category) $tag|g" | sort)
			CHKLIST="$CHKLIST $list"
			list=$(cat $PKGS | grep "$category/" | grep 'xf86-video-via' | sed 's|^[a-z0-9-]*/||g' | sed "s|.pkg.tar.gz$| ($category) $tag|g" | sort)
			CHKLIST="$CHKLIST $list"
		done
		DIALOG --checklist "Select Packages to install.  Use SPACE to select." 19 60 12 $CHKLIST 2>/tmp/.pkglist || return 1
	fi
	# Use default ftp install routine from arch livecd
	if [ "$MODE" = "ftp" ]; then
		DIALOG --msgbox "Package selection is split into two stages.  First you will select package categories that contain packages you may be interested in.  Then you will be presented with a full list of packages with your categories already selected, allowing you to fine-tune.\n\nNOTE: The BASE category is always installed, and its packages will not appear in this menu." 18 70
		# set up our install location if necessary and sync up
		# so we can get package lists
		prepare_pacman 
		# category selection hasn't been done before
		if ! [ -f /tmp/.pkgcategory ]; then
			CATLIST=""
			for i in $($PACMAN -Sg | sed "s/^base$/ /g"); do
				CATLIST="${CATLIST} ${i} - OFF"
			done
		else
			# category selection was already run at least once
			CATLIST=""
			for i in $(cat /tmp/.pkgcategory | sed 's|\"||g'); do
				CATLIST="$CATLIST $i ^ ON"
			done
			for i in $($PACMAN -Sg | sed "s/^base$/ /g"); do
				grep $i /tmp/.pkgcategory > /dev/null 2>&1 || CATLIST="$CATLIST $i - OFF"
			done
		fi
		DIALOG --checklist "Select Package Categories" 19 55 12 $CATLIST 2>/tmp/.pkgcategory || return 1

		# mash up the package lists
		COREPKGS=$($PACMAN -Sl core | cut -d' ' -f2)

		# remove base packages from the selectable list
		for i in $($PACMAN -Sg base | tail +2); do
			COREPKGS=$(echo ${COREPKGS} | sed "s/\(^${i} \| ${i} \| ${i}$\)/ /g")
		done
		# assemble a list of pre-selected packages
		for i in $(cat /tmp/.pkgcategory | sed 's|"||g'); do
			CATPKGS="$CATPKGS $($PACMAN -Sg ${i} | tail +2)"
		done
		# put together the menu list
		PKGLIST=""
		for i in ${COREPKGS}; do
			# if the package was preselected, check it
			if [ -n "$(echo $CATPKGS | grep "\(^${i} \| ${i} \| ${i}$\)")" ]; then
				PKGLIST="$PKGLIST ${i} ^ ON"
			else
				PKGLIST="$PKGLIST ${i} - OFF"
			fi
		done
		DIALOG --checklist "Select Packages To Install." 19 60 12 $PKGLIST 2>/tmp/.pkglist || return 1
	fi
	S_SELECT=1
}

doinstall()
{
	# begin install
	rm -f /tmp/pacman.log
	# all pacman output goes to /tmp/pacman.log, which we tail into a dialog
	( \
		echo "Installing Packages..." >/tmp/pacman.log ; echo >>/tmp/pacman.log ; \
		touch /tmp/setup-pacman-running ; \
		$PACMAN -S $(echo $* | sed 's|"||g') >>/tmp/pacman.log 2>&1 ; \
		echo $? >/tmp/.pacman.retcode; \
		echo >>/tmp/pacman.log; \

		if [ "$(cat /tmp/.pacman.retcode)" -gt 0 ]; then
			echo "Package Installation FAILED." >>/tmp/pacman.log
		else
			echo "Package Installation Complete." >>/tmp/pacman.log
		fi
		rm /tmp/setup-pacman-running
	) &

	sleep 2
	dialog --backtitle "$TITLE" --title " Installing... Please Wait " \
	--no-kill --tailboxbg "/tmp/pacman.log" 18 70 2>/tmp/.pid
	while [ -f /tmp/setup-pacman-running ]; do
		sleep 1
	done
	kill $(cat /tmp/.pid)
	if [ "$(cat /tmp/.pacman.retcode)" -gt 0 ]; then
		result="Installation Failed (see errors below)"
		retcode=1
	else
		result="Installation Complete"
		retcode=0
	fi
	# disabled for now
	#dialog --backtitle "$TITLE" --title " $result " \
	#	--exit-label "Continue" --textbox "/tmp/pacman.log" 18 70
	# fix the stair-stepping that --tailboxbg leaves us with
	stty onlcr

	rm -f /tmp/.pacman.retcode
	return $retcode
}

installpkg() {
	if ! [ "$S_SRC" = "1" ]; then
		DIALOG --msgbox "Error:\nYou must select Source first." 0 0
		return 1
	fi
	if [ "$MODE" = "cd" ]; then
		if [ ! -f /tmp/.pkglist -o "$S_SELECT" != "1" ]; then
			DIALOG --msgbox "You must select packages first." 0 0
			return 1
		fi
	fi
	if [ "$S_MKFS" != "1" -a "$S_MKFSAUTO" != "1" ]; then
		getdest
	fi

	DIALOG --msgbox "Package installation will begin now.  You can watch the output in the progress window. Please be patient." 0 0
	if [ "$MODE" = "cd" ]; then
	LIST=
	# fix pacman list!
	sed -i -e 's/-i686//g' -e 's/-x86_64//g' /tmp/.pkglist
	for pkg in $(cat /tmp/.pkglist); do
		pkgname=${pkg%-*-*}
		LIST="$LIST $pkgname"
	done
	fi
	if [ "$MODE" = "ftp" ]; then
		LIST="base" # always install base
		for pkg in $(cat /tmp/.pkglist); do
			LIST="$LIST $pkg"
		done
	fi
	# for a CD install, we don't need to download packages first
	if [ "$MODE" = "ftp" ]; then
		DIALOG --infobox "Downloading packages.  See $LOG for output." 6 55
		$PACMAN -Sw $(echo $LIST | sed 's|"||g') >$LOG 2>&1
		if [ $? -gt 0 ]; then
			DIALOG --msgbox "One or more packages failed to download.  You can try again by re-selecting Install Packages from the main menu." 12 65
			return 1
		fi
	fi
	# mount proc/sysfs first, so initcpio can use auto-detection if it wants
	! [ -d $DESTDIR/proc ] && mkdir $DESTDIR/proc
	! [ -d $DESTDIR/sys ] && mkdir $DESTDIR/sys
	! [ -d $DESTDIR/dev ] && mkdir $DESTDIR/dev
	mount -t proc none $DESTDIR/proc
	mount -t sysfs none $DESTDIR/sys
	mount -o bind /dev $DESTDIR/dev
	doinstall $LIST
	 if [ $? -gt 0 ]; then
		DIALOG --msgbox "One or more packages failed to install.  You can try again by re-selecting Install Packages from the main menu." 12 65
		return 1
	fi
	dialog --backtitle "$TITLE" --title " $result " \
		--exit-label "Continue" --textbox "/tmp/pacman.log" 18 70
	if [ $? -gt 0 ]; then
		return 1
	fi
	S_INSTALL=1
	# add archboot addons if activated
	if [ -d /tmp/packages ]; then
		DO_ADDON=""
		DIALOG --yesno "Would you like to install your addons packages to installed system?" 0 0 && DO_ADDON="yes"
		if [ "$DO_ADDON" = "yes" ] ; then
			DIALOG --infobox "Installing the addons packages..." 0 0
			$PACMAN -U /tmp/packages/*
		fi
	fi
	umount $DESTDIR/proc $DESTDIR/sys $DESTDIR/dev
	sync
	# Modify fstab
	if [ "$S_MKFS" = "1" -o "$S_MKFSAUTO" = "1" ]; then
		if [ -f /tmp/.fstab ]; then
			# clean fstab first from /dev entries
			sed -i -e '/^\/dev/d' $DESTDIR/etc/fstab
			# clean /media from old floppy,cd,dvd entries
			rm -r $DESTDIR/media/cd*
			rm -r $DESTDIR/media/dvd*
			rm -r $DESTDIR/media/fl*
			# add floppy,cd and dvd entries first
			for i in $(ls -d /dev/cdro* | grep -v "0"); do
				k=$(echo $i | sed -e 's|/dev/||g')
				echo "$i /media/$k   auto    ro,user,noauto,unhide   0      0" >>$DESTDIR/etc/fstab
			# create dirs in /media
				mkdir -p $DESTDIR/media/$k
			done
			for i in $(ls -d /dev/dvd* | grep -v "0"); do
				k=$(echo $i | sed -e 's|/dev/||g')
				echo "$i /media/$k   auto    ro,user,noauto,unhide   0      0" >>$DESTDIR/etc/fstab
			# create dirs in /media
				mkdir -p $DESTDIR/media/$k
			done
			for i in $(ls -d /dev/fd[0-9] | grep -v "[0-9][0-9][0-9]"); do
				k=$(echo $i | sed -e 's|/dev/||g')
				echo "$i /media/$k   auto    user,noauto   0      0" >>$DESTDIR/etc/fstab
			# create dirs in /media
				mkdir -p $DESTDIR/media/$k
			done
			sort /tmp/.fstab >>$DESTDIR/etc/fstab
		fi
	fi
}

donetwork() {
	INTERFACE=
	S_DHCP=
	ifaces=$(ifconfig -a | egrep "Ethernet" | cut -d' ' -f1 | sed 's|$| _|g')
	if [ "$ifaces" = "" ]; then
		DIALOG --yesno "Cannot find any ethernet interfaces. You probably haven't loaded\nyour network module yet.  You have two options:\n\n  1) Probe for the correct module now.\n  2) Switch to another VC (ALT-F2) and load your module\n     with the modprobe command, then switch back here (ALT-F1)\n     and continue.\n\nIf you know which module you need, you should do Step 2 and\nselect NO below.  If you don't know which module you need,\nchoose Step 1 by selecting YES below.\n\nProbe for network module?" 18 70
		if [ $? -eq 0 ]; then
			probenic
		if [ $? -gt 0 ]; then
			return 1
		fi
		fi
		ifaces=$(ifconfig -a | egrep "Ethernet" | cut -d' ' -f1 | sed 's|$| _|g')
		if [ "$ifaces" = "" ]; then
			DIALOG --msgbox "No network interfaces available." 0 0
			return 1
		fi
	fi
	while [ "$INTERFACE" = "" ]; do
		DIALOG --msgbox "Available Ethernet Interfaces:\n$(ifconfig -a | egrep "Ethernet" | sed 's# #_#g')\n\nIf your ethernet interface is not listed,\n1) Probe for the correct module now.\n2) Switch to another VC (ALT-F2) and load your module with\n   the modprobe command, then switch back here (ALT-F1)\n" 0 0
		dialog --backtitle "$TITLE" --extra-button --extra-label "Probe" --ok-label "Select" --menu "Select a network interface" 14 55 7 $ifaces 2>$ANSWER
		case $? in
			1) return 1 ;;
			0) INTERFACE=$(cat $ANSWER) ;;
			*) probenic ;;
		esac
		ifaces=$(ifconfig -a | egrep "Ethernet" | cut -d' ' -f1 | sed 's|$| _|g')
	done
	DIALOG --yesno "Do you want to use DHCP?" 0 0
	if [ $? -eq 0 ]; then
		DIALOG --infobox "Please wait.  Polling for DHCP server on $INTERFACE..." 0 0
		dhcpcd $INTERFACE >$LOG 2>&1 || DIALOG --msgbox "Failed to run dhcpcd." 0 0 || return 1
		sleep 10
		if [ ! $(ifconfig $INTERFACE | grep 'inet addr:') ]; then
			DIALOG --msgbox "DHCP request failed." 0 0 || return 1
		fi
		S_DHCP=1
	else
		NETPARAMETERS=""
		while [ "$NETPARAMETERS" = "" ]; do
			DIALOG --inputbox "Enter your IP address" 8 65 "192.168.0.2" 2>$ANSWER || return 1
			IPADDR=$(cat $ANSWER)
			DIALOG --inputbox "Enter your netmask" 8 65 "255.255.255.0" 2>$ANSWER || return 1
			SUBNET=$(cat $ANSWER)
			DIALOG --inputbox "Enter your broadcast" 8 65 "192.168.0.255" 2>$ANSWER || return 1
			BROADCAST=$(cat $ANSWER)
			DIALOG --inputbox "Enter your gateway (optional)" 8 65 "192.168.0.1" 8 65 2>$ANSWER || return 1
			GW=$(cat $ANSWER)
			DIALOG --inputbox "Enter your DNS server IP" 8 65 "192.168.0.1" 2>$ANSWER || return 1
			DNS=$(cat $ANSWER)
			DIALOG --inputbox "Enter your HTTP proxy server, for example:\nhttp://name:port\nhttp://ip:port\nhttp://username:password@ip:port\n\n Leave the field empty if no proxy is needed to install." 16 65 "" 2>$ANSWER || return 1
			PROXY_HTTP=$(cat $ANSWER)
			DIALOG --inputbox "Enter your FTP proxy server, for example:\nhttp://name:port\nhttp://ip:port\nhttp://username:password@ip:port\n\n Leave the field empty if no proxy is needed to install." 16 65 "" 2>$ANSWER || return 1
			PROXY_FTP=$(cat $ANSWER)
			DIALOG --yesno "Are these settings correct?\n\nIP address:         $IPADDR\nNetmask:            $SUBNET\nGateway (optional): $GW\nDNS server:         $DNS\nHTTP proxy server:  $PROXY_HTTP\nFTP proxy server:   $PROXY_FTP" 0 0
			case $? in
				1) ;;
				0) NETPARAMETERS="1" ;;
			esac
		done
		ifconfig $INTERFACE $IPADDR netmask $SUBNET broadcast $BROADCAST up >$LOG 2>&1 || DIALOG --msgbox "Failed to setup $INTERFACE interface." 0 0 || return 1
		if [ "$GW" != "" ]; then
			route add default gw $GW >$LOG 2>&1 || DIALOG --msgbox "Failed to setup your gateway." 0 0 || return 1
		fi
		if [ "$PROXY_HTTP" = "" ]; then
			unset http_proxy
		else
			export http_proxy=$PROXY_HTTP
		fi
		if [ "$PROXY_FTP" = "" ]; then
			unset ftp_proxy
		else
			export ftp_proxy=$PROXY_FTP
		fi
		echo "nameserver $DNS" >/etc/resolv.conf
	fi
	### Missing Proxy Configuration
	DIALOG --msgbox "The network is configured." 0 0
	S_NET=1
}

probenic() {
	workdir="$PWD"
	DIALOG --infobox "Looking for a matching ethernet module.  Please wait..." 0 0
	printk off

	cd /lib/modules/$(uname -r)/kernel/drivers/net
	if [ $? -gt 0 ]; then
		DIALOG --msgbox "No ethernet modules were found!" 0 0
		printk on
		cd "$workdir"
		return 1
	fi
	# modules with no modalias exported! status kernel 2.6.18
	NOTDETECTABLE="hp ne de4x5 wd cs89x0 eepro smc9194 seeq8005 ni52 ni65 ac3200 smc-ultra at1700 hp-plus depca eexpress 82596 de600 eth16i de620 lance ewrk3 e2100 lp486e 3c501 3c503 3c505 3c507 3c509 3c515 myri10ge"
	for mod in ${NOTDETECTABLE}; do
		modprobe $mod >/dev/null 2>&1
	done

	ifconfig -a | egrep "Ethernet" >/dev/null 2>&1
	if [ $? -gt 0 ]; then
		DIALOG --msgbox "No matching ethernet modules found." 0 0
	else
		DIALOG --msgbox "Probe succeeded.  Your network module is loaded." 0 0
	fi

	printk on
	cd "$workdir"
}

dolilo() {
	if [ ! -f $DESTDIR/etc/lilo.conf ]; then
		DIALOG --msgbox "Error: Couldn't find $DESTDIR/etc/lilo.conf.  Is LILO installed?" 0 0
		return 1
	fi
	# Try to auto-configure LILO...
	if [ "$PART_ROOT" != "" -a "$S_LILO" != "1" ]; then
		sed -i "s|vmlinuz26|vmlinuz|g" $DESTDIR/etc/lilo.conf
		sed -i "s|vmlinuz|$VMLINUZ|g" $DESTDIR/etc/lilo.conf
		if [ "$UUIDPARAMETER" = "yes" ]; then
			local _rootpart="${PART_ROOT}"
			local _uuid="$(getuuid ${PART_ROOT})"
			if [ -n "${_uuid}" ]; then
				_rootpart="/dev/disk/by-uuid/${_uuid}"
			fi
			sed -i "s|root=.*$|append=\"root=${_rootpart}\"|g" $DESTDIR/etc/lilo.conf
		else
			sed -i "s|root=.*$|root=${PART_ROOT}|g" $DESTDIR/etc/lilo.conf
		fi
	fi
	DEVS=$(finddisks _)
	DEVS="$DEVS $(findpartitions _)"
	if [ "$DEVS" = "" ]; then
		DIALOG --msgbox "No hard drives were found" 0 0
		return 1
	fi
	DIALOG --menu "Select the boot device where the LILO bootloader will be installed (usually the MBR)" 14 55 7 $DEVS 2>$ANSWER || return 1
	ROOTDEV=$(cat $ANSWER)
	sed -i "s|boot=.*$|boot=$ROOTDEV|g" $DESTDIR/etc/lilo.conf
	DIALOG --msgbox "Before installing LILO, you must review the configuration file.  You will now be put into the editor.  After you save your changes and exit the editor, LILO will be installed." 0 0
	[ "$EDITOR" ] || geteditor
	$EDITOR ${DESTDIR}/etc/lilo.conf
	DIALOG --infobox "Installing the LILO bootloader..." 0 0
	mount -t proc none $DESTDIR/proc
	mount -o bind /dev $DESTDIR/dev
	chroot $DESTDIR /sbin/lilo >$LOG 2>&1
	if [ $? -gt 0 ]; then
		umount $DESTDIR/dev $DESTDIR/proc
		DIALOG --msgbox "Error installing LILO. (see $LOG for output)" 0 0
		return 1
	fi
	umount $DESTDIR/dev $DESTDIR/proc
	DIALOG --msgbox "LILO was successfully installed." 0 0
	S_LILO=1
}

dogrub() {
	get_grub_map	
	if [ ! -f $DESTDIR/boot/grub/menu.lst ]; then
		DIALOG --msgbox "Error: Couldn't find $DESTDIR/boot/grub/menu.lst.  Is GRUB installed?" 0 0
		return 1
	fi
	# try to auto-configure GRUB...
	if [ "$PART_ROOT" != "" -a "$S_GRUB" != "1" ]; then
		grubdev=$(mapdev $PART_ROOT)
		if [ "$UUIDPARAMETER" = "yes" ]; then
			local _rootpart="${PART_ROOT}"
			local _uuid="$(getuuid ${PART_ROOT})"
			if [ -n "${_uuid}" ]; then
				_rootpart="/dev/disk/by-uuid/${_uuid}"
			fi
		fi
		# look for a separately-mounted /boot partition
		bootdev=$(mount | grep $DESTDIR/boot | cut -d' ' -f 1)
		if [ "$grubdev" != "" -o "$bootdev" != "" ]; then
			cp $DESTDIR/boot/grub/menu.lst /tmp/.menu.lst
			# remove the default entries by truncating the file at our little tag (#-*)
			head -n $(cat /tmp/.menu.lst | grep -n '#-\*' | cut -d: -f 1) /tmp/.menu.lst >$DESTDIR/boot/grub/menu.lst
			rm -f /tmp/.menu.lst
			echo "" >>$DESTDIR/boot/grub/menu.lst
			echo "# (0) Arch Linux" >>$DESTDIR/boot/grub/menu.lst
			echo "title  Arch Linux" >>$DESTDIR/boot/grub/menu.lst
			subdir=
			if [ "$bootdev" != "" ]; then
				grubdev=$(mapdev $bootdev)
			else
				subdir="/boot"
			fi
			echo "root   $grubdev" >>$DESTDIR/boot/grub/menu.lst
			if [ "$UUIDPARAMETER" = "yes" ]; then
				echo "kernel $subdir/$VMLINUZ root=${_rootpart} ro" >>$DESTDIR/boot/grub/menu.lst
			else
				echo "kernel $subdir/$VMLINUZ root=$PART_ROOT ro" >>$DESTDIR/boot/grub/menu.lst
			fi
			if [ "$VMLINUZ" = "vmlinuz26" ]; then
				echo "initrd $subdir/kernel26.img" >>$DESTDIR/boot/grub/menu.lst
			fi
			echo "" >>$DESTDIR/boot/grub/menu.lst
			# adding fallback/full image
			echo "# (1) Arch Linux" >>$DESTDIR/boot/grub/menu.lst
			echo "title  Arch Linux Fallback" >>$DESTDIR/boot/grub/menu.lst
			echo "root   $grubdev" >>$DESTDIR/boot/grub/menu.lst
			if [ "$UUIDPARAMETER" = "yes" ]; then
				echo "kernel $subdir/$VMLINUZ root=${_rootpart} ro" >>$DESTDIR/boot/grub/menu.lst
			else
				echo "kernel $subdir/$VMLINUZ root=$PART_ROOT ro" >>$DESTDIR/boot/grub/menu.lst
			fi
			if [ "$VMLINUZ" = "vmlinuz26" ]; then
				echo "initrd $subdir/kernel26-fallback.img" >>$DESTDIR/boot/grub/menu.lst
			fi
			echo "" >>$DESTDIR/boot/grub/menu.lst
			echo "# (1) Windows" >>$DESTDIR/boot/grub/menu.lst
			echo "#title Windows" >>$DESTDIR/boot/grub/menu.lst
			echo "#rootnoverify (hd0,0)" >>$DESTDIR/boot/grub/menu.lst
			echo "#makeactive" >>$DESTDIR/boot/grub/menu.lst
			echo "#chainloader +1" >>$DESTDIR/boot/grub/menu.lst
		fi
	fi

	DIALOG --msgbox "Before installing GRUB, you must review the configuration file.  You will now be put into the editor.  After you save your changes and exit the editor, you can install GRUB." 0 0
	[ "$EDITOR" ] || geteditor
	$EDITOR ${DESTDIR}/boot/grub/menu.lst

	DEVS=$(finddisks _)
	DEVS="$DEVS $(findpartitions _)"
	if [ "$DEVS" = "" ]; then
		DIALOG --msgbox "No hard drives were found" 0 0
		return 1
	fi
	DIALOG --menu "Select the boot device where the GRUB bootloader will be installed (usually the MBR)" 14 55 7 $DEVS 2>$ANSWER || return 1
	ROOTDEV=$(cat $ANSWER)
	DIALOG --infobox "Installing the GRUB bootloader..." 0 0
	cp -a $DESTDIR/usr/lib/grub/i386-pc/* $DESTDIR/boot/grub/
	sync
	# freeze xfs filesystems to enable grub installation on xfs filesystems
	if [ -x /usr/sbin/xfs_freeze ]; then
		/usr/sbin/xfs_freeze -f $DESTDIR/boot > /dev/null 2>&1
		/usr/sbin/xfs_freeze -f $DESTDIR/ > /dev/null 2>&1
	fi
	# look for a separately-mounted /boot partition
	bootpart=$(mount | grep $DESTDIR/boot | cut -d' ' -f 1)
	if [ "$bootpart" = "" ]; then
		if [ "$PART_ROOT" = "" ]; then
			DIALOG --inputbox "Enter the full path to your root device" 8 65 "/dev/sda3" 2>$ANSWER || return 1
			bootpart=$(cat $ANSWER)
		else
			bootpart=$PART_ROOT
		fi
	fi
	DIALOG --defaultno --yesno "Do you have your system installed on software raid?\nAnswer 'YES' to install grub to another hard disk."  0 0
	if [ $? -eq 0 ]; then
		DIALOG --menu "Please select the boot partition device, this cannot be autodetected!\nPlease redo grub installation for all partitions you need it!" 14 55 7 $DEVS 2>$ANSWER || return 1
		bootpart=$(cat $ANSWER)
	fi	
	bootpart=$(mapdev $bootpart)
	bootdev=$(mapdev $ROOTDEV)
	if [ "$bootpart" = "" ]; then
		DIALOG --msgbox "Error: Missing/Invalid root device: $bootpart" 0 0
		return 1
	fi
	$DESTDIR/sbin/grub --no-floppy --batch >/tmp/grub.log 2>&1 <<EOF
root $bootpart
setup $bootdev
quit
EOF
	cat /tmp/grub.log >$LOG
	# unfreeze xfs filesystems
	if [ -x /usr/sbin/xfs_freeze ]; then
		/usr/sbin/xfs_freeze -u $DESTDIR/boot > /dev/null 2>&1
		/usr/sbin/xfs_freeze -u $DESTDIR/ > /dev/null 2>&1
	fi

	if grep "Error [0-9]*: " /tmp/grub.log >/dev/null; then
		DIALOG --msgbox "Error installing GRUB. (see $LOG for output)" 0 0
		return 1
	fi
	DIALOG --msgbox "GRUB was successfully installed." 0 0
	S_GRUB=1
}

select_source()
{
	if ! [ $(which $DLPROG) ]; then
		DIALOG --menu "Please select an installation source" 10 35 3 \
		"1" "CD-ROM or OTHER SOURCE" 2>$ANSWER || return 1
	else
		DIALOG --menu "Please select an installation source" 10 35 3 \
		"1" "CD-ROM or OTHER SOURCE" \
		"2" "FTP/HTTP" 2>$ANSWER || return 1
	fi

	case $(cat $ANSWER) in
		"1")
			MODE="cd"
			;;
		"2")
			MODE="ftp"
			;;
	esac 

	if [ "$MODE" = "cd" ]; then
		TITLE="Arch Linux CDROM or OTHER SOURCE Installation"
		getsource
	else
		TITLE="Arch Linux FTP/HTTP Installation"
		DIALOG --msgbox "If you wish to load your ethernet modules manually, please do so now (consoles 1 thru 6 are active)." 12 65
		while $(/bin/true); do
		    DIALOG --menu "FTP Installation" 10 35 3 \
		    "0" "Setup Network" \
		    "1" "Choose Mirror" \
		    "2" "Return to Main Menu" 2>$ANSWER

		    case "$(cat $ANSWER)" in
			"0")
				donetwork ;;
			"1")
				getsource ;;
			 *)
				break ;;
		    esac
		done
	fi
}

set_clock()
{
	if [ -e /usr/bin/tz ]; then 
		tz
	else
		DIALOG --msgbox "Error:\ntz script not found, aborting clock setting" 0 0
	fi
}

set_keyboard()
{
	if [ -e /usr/bin/km ]; then 
		km
	else
		DIALOG --msgbox "Error:\nkm script not found, aborting keyboard and console setting" 0 0
	fi
}

prepare_harddrive()
{
	S_MKFSAUTO=0
	S_MKFS=0
	DONE=0
	UUIDPARAMETER=""
	NEXTITEM=""
	DIALOG --yesno "Do you want to use UUID device name scheme,\ninstead of kernel device name scheme?" 0 0 && UUIDPARAMETER=yes
	while [ "$DONE" = "0" ]; do
		if [ -n "$NEXTITEM" ]; then
			DEFAULT="--default-item $NEXTITEM"
		else
			DEFAULT=""
		fi
		dialog $DEFAULT --backtitle "$TITLE" --menu "Prepare Hard Drive" 12 60 5 \
			"1" "Auto-Prepare (erases the ENTIRE hard drive)" \
			"2" "Partition Hard Drives" \
			"3" "Set Filesystem Mountpoints" \
			"4" "Return to Main Menu" 2>$ANSWER
		NEXTITEM="$(cat $ANSWER)"
		case $(cat $ANSWER) in
			"1")
				DISCS=$(finddisks)
				if [ $(echo $DISCS | wc -w) -gt 1 ]; then
					DIALOG --msgbox "Available Disks:\n\n$(for i in $(finddisks); do dmesg | grep $(echo $i | sed 's#/dev/##g') | grep sectors | sort -u | cut -d')' -f1 |sed -e 's/ /|/g' -e 's/SCSI|device|//g' -e 's/(//g'; done)\n" 0 0
					DIALOG --menu "Select the hard drive to use" 14 55 7 $(finddisks _) 2>$ANSWER || return 1
					DISC=$(cat $ANSWER)
				else
					DISC=$DISCS
				fi
					SET_DEFAULTFS=""
					BOOT_PART_SET=""
					SWAP_PART_SET=""
					ROOT_PART_SET=""
					CHOSEN_FS=""
					DISC_SIZE=$(dmesg | grep $(echo $DISC | sed 's#/dev/##g') | grep sectors | sort -u | cut -d'(' -f2 | sed -e 's# .*##g')
					while [ "$SET_DEFAULTFS" = "" ]; do
						FSOPTS="ext2 Ext2 ext3 Ext3"
						[ "$(which mkreiserfs 2>/dev/null)" ] && FSOPTS="$FSOPTS reiserfs Reiser3"
						[ "$(which mkfs.xfs 2>/dev/null)" ]   && FSOPTS="$FSOPTS xfs XFS"
						[ "$(which mkfs.jfs 2>/dev/null)" ]   && FSOPTS="$FSOPTS jfs JFS"
						while [ "$BOOT_PART_SET" = "" ]; do
							DIALOG --inputbox "Enter the size (MegaByte/MB) of your /boot partition,\n(minimum value is 16).\n\nDisk space left: $DISC_SIZE (MegaByte/MB)" 8 65 "32" 2>$ANSWER || return 1
							BOOT_PART_SIZE="$(cat $ANSWER)"
							if [ "$BOOT_PART_SIZE" = ""  ]; then
								DIALOG --msgbox "ERROR: You have entered a wrong size, please enter again." 0 0
							else
								if [ "$BOOT_PART_SIZE" -ge "$DISC_SIZE" -o "$BOOT_PART_SIZE" -lt "16" -o "$SBOOT_PART_SIZE" = "$DISC_SIZE" ]; then
									DIALOG --msgbox "ERROR: You have entered a wrong size, please enter again." 0 0
								else
									BOOT_PART_SET=1
								fi
							fi
						done
						DISC_SIZE=$(($DISC_SIZE-$BOOT_PART_SIZE))
						while [ "$SWAP_PART_SET" = "" ]; do
							DIALOG --inputbox "Enter the size (MegaByte/MB) of your swap partition,\n(minimum value is > 0).\n\nDisk space left: $DISC_SIZE (MegaByte/MB)" 8 65 "256" 2>$ANSWER || return 1
							SWAP_PART_SIZE=$(cat $ANSWER)
							if [ "$SWAP_PART_SIZE" = "" -o  "$SWAP_PART_SIZE" = "0" ]; then
								DIALOG --msgbox "ERROR: You have entered a wrong size, please enter again." 0 0
							else
								if [ "$SWAP_PART_SIZE" -ge "$DISC_SIZE" ]; then
									DIALOG --msgbox "ERROR: You have entered a wrong size, please enter again." 0 0
								else
									SWAP_PART_SET=1
								fi
							fi
						done
						DISC_SIZE=$(($DISC_SIZE-$SWAP_PART_SIZE))
						while [ "$ROOT_PART_SET" = "" ]; do
							DIALOG --inputbox "Enter the size (MegaByte/MB) of your / partition,\nthe /home partition will take all the left space.\n\nDisk space left:  $DISC_SIZE (MegaByte/MB)" 8 65 "7500" 2>$ANSWER || return 1
							ROOT_PART_SIZE=$(cat $ANSWER)
							if [ "$ROOT_PART_SIZE" = "" -o "$ROOT_PART_SIZE" = "0" ]; then
								DIALOG --msgbox "ERROR: You have entered a wrong size, please enter again." 0 0
							else
								if [ "$ROOT_PART_SIZE" -ge "$DISC_SIZE" ]; then
									DIALOG --msgbox "ERROR: You have entered a wrong size, please enter again." 0 0
								else
									DIALOG --yesno "$(($DISC_SIZE-$ROOT_PART_SIZE)) (MegaByte/MB) will be used for your /home partition?" 0 0 && ROOT_PART_SET=1
								fi
							fi
						done
						while [ "$CHOSEN_FS" = "" ]; do
							DIALOG --menu "Select a filesystem for / and /home" 13 45 6 $FSOPTS 2>$ANSWER || return 1
									FSTYPE=$(cat $ANSWER)
							DIALOG --yesno "$FSTYPE will be used for / and /home?" 0 0 && CHOSEN_FS=1
						done
						SET_DEFAULTFS=1
					done
				REAL_DEFAULTFS=$(echo $DEFAULTFS | sed -e "s|/:7500:ext3|/:$ROOT_PART_SIZE:$FSTYPE|g" -e "s|/home:\*:ext3|/home:\*:$FSTYPE|g" -e "s|swap:256|swap:$SWAP_PART_SIZE|g" -e "s|/boot:32|/boot:$BOOT_PART_SIZE|g")
				DIALOG --defaultno --yesno "$DISC will be COMPLETELY ERASED!  Are you absolutely sure?" 0 0 \
					&& mksimplefs $DISC "$REAL_DEFAULTFS" ;;
			"2")
				partition ;;
			"3")
				PARTFINISH=""
				mountpoints ;;
			*)
				DONE=1 ;;
		esac
	done
	NEXTITEM="3"
}

configure_system()
{
	HWDETECT=""
	HWPARAMETER=""
	DSDT_ENABLE=""
	DIALOG --yesno "PRECONFIGURATION?\n-----------------\n\nDo you want to use 'hwdetect' for:\n'/etc/rc.conf' and '/etc/mkinitcpio.conf'?\n\nThis ensures consistent ordering of your hard disk controllers,\nnetwork and sound devices.\n\nIt is recommended to say 'YES' here." 18 70 && HWDETECT="yes"
	if [ "$HWDETECT" = "yes" ]; then
		if /usr/bin/vmware-detect; then 
			HWPARAMETER="$HWPARAMETER --vmware"
		fi
		grep -qw ide-legacy /proc/cmdline && HWPARAMETER="$HWPARAMETER --ide-legacy"
		DIALOG --defaultno --yesno "Do you need support for booting from usb devices?" 0 0 && HWPARAMETER="$HWPARAMETER --usb"
		DIALOG --defaultno --yesno "Do you need support for booting from firewire devices?" 0 0 && HWPARAMETER="$HWPARAMETER --fw"
		DIALOG --defaultno --yesno "Do you need support for booting from pcmcia devices?" 0 0 && HWPARAMETER="$HWPARAMETER --pcmcia"
		DIALOG --defaultno --yesno "Do you need support for booting from nfs shares?" 0 0 && HWPARAMETER="$HWPARAMETER --nfs"
		DIALOG --defaultno --yesno "Do you need support for booting from software raid arrays?" 0 0 && HWPARAMETER="$HWPARAMETER --raid"
		if [ -e $DESTDIR/lib/initcpio/hooks/raid-partitions ]; then
			DIALOG --defaultno --yesno "Do you need support for booting from software raid mdp/partition arrays?" 0 0 && HWPARAMETER="$HWPARAMETER --raid-partitions"
		fi
		if [ -e $DESTDIR/lib/initcpio/hooks/dmraid ]; then
			DIALOG --defaultno --yesno "Do you need support for booting from hardware dmraid arrays?" 0 0 && HWPARAMETER="$HWPARAMETER --dmraid"
		fi
		DIALOG --defaultno --yesno "Do you need support for booting from lvm2 volumes?" 0 0 && HWPARAMETER="$HWPARAMETER --lvm2"
		DIALOG --defaultno --yesno "Do you need support for booting from encrypted volumes?" 0 0 && HWPARAMETER="$HWPARAMETER --encrypt"
		DIALOG --defaultno --yesno "Do you need support for booting the kernel with a custom DSDT file?" 0 0 && DSDT_ENABLE=1
		if [ "$DSDT_ENABLE" = "1" ]; then
			while [ "$DSDT" = "" ]; do
				DIALOG --inputbox "Enter the custom DSDT file (with full path)" 8 65 "" 2>$ANSWER || return 1
				DSDT=$(cat $ANSWER)
				if [ -s "$DSDT" ]; then
					cp $DSDT $DESTDIR/lib/initcpio/custom.dsdt
					HWPARAMETER="$HWPARAMETER --dsdt"
				else
					DIALOG --msgbox "ERROR: You have entered a wrong file name, please enter again." 0 0
					DSDT=""
				fi
			done
		fi
		# add always keymap
		HWPARAMETER="$HWPARAMETER --keymap"
		HWDETECTHOSTCONTROLLER=""
		HWDETECTHOOKS=""
		HWDETECTRC=""
		HWDETECTHOSTCONTROLLER="$(hwdetect --hostcontroller $HWPARAMETER)"
		HWDETECTHOOKS="$(hwdetect --hooks-dir=$DESTDIR/lib/initcpio/install --hooks $HWPARAMETER)"
		HWDETECTRC="$(echo $(hwdetect --net --sound $HWPARAMETER)| sed -e 's#.*) ##g')"
		[ -n "$HWDETECTHOSTCONTROLLER" ] && sed -i -e "s/^MODULES=.*/$HWDETECTHOSTCONTROLLER/g" ${DESTDIR}/etc/mkinitcpio.conf
		[ -n "$HWDETECTHOOKS" ] && sed -i -e "s/^HOOKS=.*/$HWDETECTHOOKS/g" ${DESTDIR}/etc/mkinitcpio.conf
		[ -n "$HWDETECTRC" ] && sed -i -e "s/^MODULES=.*/$HWDETECTRC/g" ${DESTDIR}/etc/rc.conf
	fi
	if [ -s /tmp/.keymap ]; then
		DIALOG --yesno "Do you want to use the keymap: $(cat /tmp/.keymap | sed -e 's/\..*//g') in rc.conf?" 0 0 && sed -i -e "s/^KEYMAP=.*/KEYMAP=\"$(cat /tmp/.keymap | sed -e 's/\..*//g')\"/g" ${DESTDIR}/etc/rc.conf
	fi
	if [ -s /tmp/.font ]; then
		DIALOG --yesno "Do you want to use the consolefont: $(cat /tmp/.font | sed -e 's/\..*//g') in rc.conf?" 0 0 && sed -i -e "s/^CONSOLEFONT=.*/CONSOLEFONT=\"$(cat /tmp/.font | sed -e 's/\..*//g')\"/g" ${DESTDIR}/etc/rc.conf
	fi
	if [ -s  /tmp/.hardwareclock ]; then
		DIALOG --yesno "Do you want to use the hardwareclock: $(cat /tmp/.hardwareclock | sed -e 's/\..*//g') in rc.conf?" 0 0 && sed -i -e "s/^HARDWARECLOCK=.*/HARDWARECLOCK=\"$(cat /tmp/.hardwareclock | sed -e 's/\..*//g')\"/g" ${DESTDIR}/etc/rc.conf
	fi
	if [ -s  /tmp/.timezone ]; then
		DIALOG --yesno "Do you want to use the timezone: $(cat /tmp/.timezone | sed -e 's/\..*//g') in rc.conf?" 0 0 && sed -i -e "s#^TIMEZONE=.*#TIMEZONE=\"$(cat /tmp/.timezone | sed -e 's/\..*//g')\"#g" ${DESTDIR}/etc/rc.conf
	fi
	if [ "$S_NET" = "1" ]; then
		DIALOG --yesno "Do you want to use the previous network settings in rc.conf and resolv.conf?\nIf you used Proxy settings, they will be written to /etc/profile.d/proxy.sh" 0 0 && (
		if [ "$S_DHCP" != "1" ]; then 
			sed -i -e "s#eth0=\"eth0#$INTERFACE=\"$INTERFACE#g" ${DESTDIR}/etc/rc.conf
			sed -i -e "s# 192.168.0.2 # $IPADDR #g" ${DESTDIR}/etc/rc.conf
			sed -i -e "s# 255.255.255.0 # $SUBNET #g" ${DESTDIR}/etc/rc.conf
			sed -i -e "s# 192.168.0.255\"# $BROADCAST\"#g" ${DESTDIR}/etc/rc.conf
			sed -i -e "s#eth0)#$INTERFACE)#g" ${DESTDIR}/etc/rc.conf 
				if [ "$GW" != "" ]; then 
					sed -i -e "s#gw 192.168.0.1#gw $GW#g" ${DESTDIR}/etc/rc.conf 
					sed -i -e "s#!gateway#gateway#g" ${DESTDIR}/etc/rc.conf 
				fi 
			echo "nameserver $DNS" >> ${DESTDIR}/etc/resolv.conf 
		else  
			sed -i -e "s#eth0=\"eth0.*#$INTERFACE=\"dhcp\"#g" ${DESTDIR}/etc/rc.conf
		fi
		if [ "$PROXY_HTTP" != "" ]; then
			echo "export http_proxy=$PROXY_HTTP" >> ${DESTDIR}/etc/profile.d/proxy.sh;
			chmod a+x ${DESTDIR}/etc/profile.d/proxy.sh
		fi
		if [ "$PROXY_FTP" != "" ]; then
			echo "export ftp_proxy=$PROXY_FTP" >> ${DESTDIR}/etc/profile.d/proxy.sh;
			chmod a+x ${DESTDIR}/etc/profile.d/proxy.sh
		fi)
	fi
	[ "$EDITOR" ] || geteditor
	DONE=0
	FILE=""
	while [ "$EDITOR" != "" -a "$DONE" = "0" ]; do
		if [ -n "$FILE" ]; then
			DEFAULT="--default-item $FILE"
		else
			DEFAULT=""
		fi
		dialog $DEFAULT --backtitle "$TITLE" --menu "Configuration" 19 80 16 \
			"/etc/rc.conf" "System Config" \
			"/etc/fstab" "Filesystem Mountpoints" \
			"/etc/mkinitcpio.conf" "Initramfs Config" \
			"/etc/modprobe.conf" "Kernel Modules (for 2.6.x)" \
			"/etc/resolv.conf" "DNS Servers" \
			"/etc/hosts" "Network Hosts" \
			"/etc/hosts.deny" "Denied Network Services" \
			"/etc/hosts.allow" "Allowed Network Services" \
			"/etc/locale.gen" "Glibc Locales" \
			"Root-Password" "Set the root password" \
			"Pacman-Mirror" "Set the primary pacman mirror" \
			"_" "Return to Main Menu" 2>$ANSWER
		FILE=$(cat $ANSWER)

		if [ "$FILE" = "_" -o "$FILE" = "" ]; then
			mount -t proc none $DESTDIR/proc
			mount -t sysfs none $DESTDIR/sys
			mount -o bind /dev $DESTDIR/dev
			# all pacman output goes to /tmp/pacman.log, which we tail into a dialog
			( \
			touch /tmp/setup-mkinitcpio-running
			echo "Initramfs progress ..." > /tmp/initramfs.log; echo >> /tmp/initramfs.log
			chroot $DESTDIR /sbin/mkinitcpio -p kernel26 >>/tmp/initramfs.log 2>&1
			echo >> /tmp/initramfs.log
			rm -f /tmp/setup-mkinitcpio-running 
			) &
			sleep 2 
			dialog --backtitle "$TITLE" --title "Rebuilding initramfs images ..." --no-kill --tailboxbg "/tmp/initramfs.log" 18 70
			while [ -f /tmp/setup-mkinitcpio-running ]; do
				sleep 1
			done
			umount $DESTDIR/proc $DESTDIR/sys $DESTDIR/dev
			DONE=1 
		else
			if [ "$FILE" = "/etc/mkinitcpio.conf" ]; then
				DIALOG --msgbox "The mkinitcpio.conf file controls which modules will be placed into the initramfs for your system's kernel.\n\n- Non US keymap users should add 'keymap' to HOOKS= array\n- USB keyboard users should add 'usbinput' to HOOKS= array\n- If you install under VMWARE add 'BusLogic' to MODULES= array\n- raid, lvm2, encrypt are not enabled by default\n- 2 or more disk controllers, please specify the correct module\n  loading order in MODULES= array \n\nMost of you will not need to change anything in this file." 18 70
				HOOK_ERROR=""
			fi
			if ! [ "$FILE" = "Root-Password" -o "$FILE" = "Pacman-Mirror" ]; then
				if [ "$FILE" = "/etc/locale.gen" ]; then
				# enable glibc locales from rc.conf
					for i in $(grep "^LOCALE" ${DESTDIR}/etc/rc.conf | sed -e 's/.*="//g' -e's/\..*//g'); do
						sed -i -e "s/^#$i/$i/g" ${DESTDIR}/etc/locale.gen
					done
				fi
					$EDITOR ${DESTDIR}${FILE}
			else
				if [ "$FILE" = "Root-Password" ]; then
					ROOTPW=""
					while [ "$ROOTPW" = "" ]; do
						chroot ${DESTDIR} passwd root && ROOTPW=1
					done
				else
					SAMEMIRROR=""
					mirrorlist="${DESTDIR}/etc/pacman.d/mirrorlist"
					if [ "$MODE" = "ftp" -a "${SYNC_SERVER}" != "" ]; then
						DIALOG --yesno "Would you like to use the same MIRROR you used for installation?" 0 0&& SAMEMIRROR="yes"
					fi
					if ! [ "$SAMEMIRROR" = "yes" ]; then
						DIALOG --msgbox "WARNING:\n\n- Please keep in mind ftp.archlinux.org is throttled!\n- Please select another mirror to get full download speed." 18 70
						# this will find all mirrors in the mirrorlist, commented out or not
						PAC_MIRRORS=$(egrep -o '((ftp)|(http))://[^/]*' "${DESTDIR}/etc/pacman.d/mirrorlist" | sed 's|$| _|g')
						DIALOG --menu "Select the primary Pacman mirror" 14 55 7 $PAC_MIRRORS "Custom" "_" 2>$ANSWER || return 1
						PAC_SYNC_SERVER="$(cat $ANSWER)"
						if [ "$PAC_SYNC_SERVER" = "Custom" ]; then
							DIALOG --inputbox "Enter the full URL to packages, for example:\nhttp://server.org/archlinux/\$repo/os/$(uname -m)" 8 65 "http://" 2>$ANSWER || return 1
							PAC_SYNC_SERVER="$(cat $ANSWER)"
						fi
					else
						PAC_SYNC_SERVER="$(echo ${SYNC_URL} | sed 's/core/\$repo/g')"
					fi
					# comment out all existing mirrors
					sed -i -e 's/^Server/#Server/g' "$mirrorlist"
					# add our new entry at the end of the file
					echo "# Setup-configured entry" >> "$mirrorlist"
					echo Server = $(egrep -o "$PAC_SYNC_SERVER.*" "$mirrorlist") >> "$mirrorlist"
				fi
			fi
			if [ "$FILE" = "/etc/locale.gen" ]; then
				chroot ${DESTDIR} locale-gen
			fi
			if [ "$FILE" = "/etc/mkinitcpio.conf" ]; then
				for i in $(cat ${DESTDIR}/etc/mkinitcpio.conf | grep ^HOOKS | sed -e 's/"//g' -e 's/HOOKS=//g'); do 
					[ -e ${DESTDIR}/lib/initcpio/install/$i ] || HOOK_ERROR=1 
				done
				if [ "$HOOK_ERROR" = "1" ]; then
					DIALOG --msgbox "ERROR: Detected error in 'HOOKS=' line, please correct HOOKS= in /etc/mkinitcpio.conf!" 18 70
				fi
			fi
			if [ "$FILE" = "/etc/rc.conf" ]; then
				TIMEZONE=""
				eval $(grep "^TIMEZONE" ${DESTDIR}/etc/rc.conf)
				if [ "$TIMEZONE" != "" -a -e ${DESTDIR}/usr/share/zoneinfo/$TIMEZONE ]; then
					cp ${DESTDIR}/usr/share/zoneinfo/$TIMEZONE ${DESTDIR}/etc/localtime
					cp ${DESTDIR}/usr/share/zoneinfo/$TIMEZONE /etc/localtime
				fi
				if [ ! -f ${DESTDIR}/var/lib/hwclock/adjtime ]; then
						echo "0.0 0 0.0" > ${DESTDIR}/var/lib/hwclock/adjtime
				fi
				eval $(grep "^HARDWARECLOCK" ${DESTDIR}/etc/rc.conf)
				if [ "$HARDWARECLOCK" = "UTC" ]; then
					chroot ${DESTDIR} /sbin/hwclock --directisa --utc --hctosys
				else
					chroot ${DESTDIR} /sbin/hwclock --directisa --localtime --hctosys
				fi
				# ugly hack:
				for line in $(sort --reverse -t: -k3 /tmp/.parts); do
					PART=$(echo $line | cut -d: -f 1)
					FSTYPE=$(echo $line | cut -d: -f 2)
					MP=$(echo $line | cut -d: -f 3)
					if [ "$MP" != "swap" ]; then
						umount ${DESTDIR}${MP}
					fi
				done
				for line in $(sort -t: -k3 /tmp/.parts); do
					PART=$(echo $line | cut -d: -f 1)
					FSTYPE=$(echo $line | cut -d: -f 2)
					MP=$(echo $line | cut -d: -f 3)
					if [ "$MP" != "swap" ]; then
					mount -t ${FSTYPE} ${PART} ${DESTDIR}${MP}
					fi
				done
				# end of hack
			fi
		fi
	done
}

install_bootloader()
{
	DIALOG --menu "Which bootloader would you like to use?  Grub is the Arch default.\n\n" \
		10 55 2 \
		"GRUB" "Use the GRUB bootloader (default)" \
		"LILO" "Use the LILO bootloader" 2>$ANSWER
	case $(cat $ANSWER) in
		"GRUB") dogrub ;;
		"LILO") dolilo ;;
	esac
}

mainmenu() {
	if [ -n "$NEXTITEM" ]; then
		DEFAULT="--default-item $NEXTITEM"
	else
		DEFAULT=""
	fi
	dialog $DEFAULT --backtitle "$TITLE" --title " MAIN MENU " \
	--menu "Use the UP and DOWN arrows to navigate menus.  Use TAB to switch between buttons and ENTER to select." 17 55 13 \
	"0" "Keyboard And Console Setting" \
	"1" "Set Clock" \
	"2" "Prepare Hard Drive" \
	"3" "Select Source" \
	"4" "Select Packages" \
	"5" "Install Packages" \
	"6" "Configure System" \
	"7" "Install Bootloader" \
	"8" "Exit Install" 2>$ANSWER
	NEXTITEM="$(cat $ANSWER)"
	case $(cat $ANSWER) in
		"0")
			set_keyboard ;;
		"1")
			set_clock ;;
		"2")
			prepare_harddrive ;;
		"3")
			select_source ;;
		"4")
			selectpkg ;;
		"5")
			installpkg ;;
		"6")
			configure_system ;;
		"7")
			install_bootloader ;;
		"8")
			if [ "$S_SRC" = "1" -a "$MODE" = "cd" ]; then
				umount /src >/dev/null 2>&1
			fi
			[ -e /tmp/.setup-running ] && rm /tmp/.setup-running
			clear
			echo ""
			echo "If the install finished successfully, you can now type 'reboot'"
			echo "to restart the system."
			echo ""
			exit 0 ;;
		*)
			DIALOG --yesno "Abort Installation?" 6 40 &&[ -e /tmp/.setup-running ] && rm /tmp/.setup-running && clear && exit 0
			;;
	esac
}

#####################
## begin execution ##
if [ -e /tmp/.setup-running ]; then
	echo "HINT:"
	echo "setup already runs on a different console!"
	echo "Please remove /tmp/.setup-running first to launch setup!"
	exit 1
fi 
: >/tmp/.setup-running
: >/tmp/.setup

DIALOG --msgbox "Welcome to the Arch Linux Installation program.  The install process is fairly straightforward, and you should run through the options in the order they are presented.  If you are unfamiliar with partitioning/making filesystems, you may want to consult some documentation before continuing.  You can view all output from commands by viewing your VC7 console (ALT-F7).  ALT-F1 will bring you back here." 14 65

while $(/bin/true); do
	mainmenu
done

clear
exit 0
