summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorDieter Plaetinck <dieter@plaetinck.be>2008-11-02 22:04:36 +0100
committerDieter Plaetinck <dieter@plaetinck.be>2008-11-02 22:04:36 +0100
commit4019db7a540d6dfcef6431cfc11ca748595e2ca1 (patch)
treefc47df27708360c71699609f80d0b732b28412d8 /src/core
parentc8a41a8f2afdb46e9da3bc9a677210b74b82eaab (diff)
file hierarchy overhaul. now a structure that makes more sense: user and core separated. we now differentiate between procedures and libraries - no more "profiles" - + some bug fixed + probably quite a few introduced + runtime directory + separated my own stuff more
Diffstat (limited to 'src/core')
-rw-r--r--src/core/libs/lib-blockdevices-filesystems.sh285
-rw-r--r--src/core/libs/lib-misc.sh42
-rw-r--r--src/core/libs/lib-network.sh33
-rw-r--r--src/core/libs/lib-pacman.sh177
-rw-r--r--src/core/libs/lib-software.sh57
-rw-r--r--src/core/libs/lib-ui.sh246
-rw-r--r--src/core/procedures/base143
-rw-r--r--src/core/procedures/interactive-DRAFT842
-rw-r--r--src/core/procedures/quickinst-DRAFT40
9 files changed, 1865 insertions, 0 deletions
diff --git a/src/core/libs/lib-blockdevices-filesystems.sh b/src/core/libs/lib-blockdevices-filesystems.sh
new file mode 100644
index 0000000..a3bc099
--- /dev/null
+++ b/src/core/libs/lib-blockdevices-filesystems.sh
@@ -0,0 +1,285 @@
+#!/bin/sh
+
+# procedural code from quickinst functionized and fixed.
+# there were functions like this in the setup script too, with some subtle differences. see below
+# NOTE: why were the functions in the setup called CHROOT_mount/umount? this is not chrooting ?
+target_special_fs ()
+{
+ [ "$1" = on -o "$1" = off ] || die_error "special_fs needs on/off argument"
+ if [ "$1" = on ]
+ then
+ # mount proc/sysfs first, so mkinitrd can use auto-detection if it wants
+ ! [ -d $var_TARGET_DIR/proc ] && mkdir $var_TARGET_DIR/proc
+ ! [ -d $var_TARGET_DIR/sys ] && mkdir $var_TARGET_DIR/sys
+ ! [ -d $var_TARGET_DIR/dev ] && mkdir $var_TARGET_DIR/dev
+ #mount, if not mounted yet
+ mount | grep -q "$var_TARGET_DIR/proc" || mount -t proc none $var_TARGET_DIR/proc || die_error "Could not mount $var_TARGET_DIR/proc" #NOTE: setup script uses mount -t proc proc ? what's best?
+ mount | grep -q "$var_TARGET_DIR/sys" || mount -t sysfs none $var_TARGET_DIR/sys || die_error "Could not mount $var_TARGET_DIR/sys" # NOTE: setup script uses mount -t sysfs sysfs ? what's best?
+ mount | grep -q "$var_TARGET_DIR/dev" || mount -o bind /dev $var_TARGET_DIR/dev || die_error "Could not mount $var_TARGET_DIR/dev"
+ elif [ "$1" = off ]
+ then
+ umount $var_TARGET_DIR/proc || die_error "Could not umount $var_TARGET_DIR/proc"
+ umount $var_TARGET_DIR/sys || die_error "Could not umount $var_TARGET_DIR/sys"
+ umount $var_TARGET_DIR/dev || die_error "Could not umount $var_TARGET_DIR/dev"
+ fi
+}
+
+
+# taken from setup
+# Disable swap and all mounted partitions for the destination system. Unmount
+# the destination root partition last!
+target_umountall()
+{
+ notify "Disabling swapspace, unmounting already mounted disk devices..."
+ swapoff -a >/dev/null 2>&1
+ umount $(mount | grep -v "${var_TARGET_DIR} " | grep "${var_TARGET_DIR}" | sed 's|\ .*||g') >/dev/null 2>&1
+ umount $(mount | grep "${var_TARGET_DIR} " | sed 's|\ .*||g') >/dev/null 2>&1
+}
+
+
+# literally taken from setup script
+finddisks() {
+ workdir="$PWD"
+ cd /sys/block
+ # ide devices
+ for dev in $(ls | egrep '^hd'); do
+ if [ "$(cat $dev/device/media)" = "disk" ]; then
+ echo "/dev/$dev"
+ [ "$1" ] && echo $1
+ fi
+ done
+ #scsi/sata devices
+ for dev in $(ls | egrep '^sd'); do
+ # TODO: what is the significance of 5?
+ if ! [ "$(cat $dev/device/type)" = "5" ]; then
+ echo "/dev/$dev"
+ [ "$1" ] && echo $1
+ 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(). taken and modified from setup. this can probably be more improved. return an exit code, rely on blkid's exit codes etc.
+# converts /dev/[hs]d?[0-9] devices to UUIDs
+#
+# parameters: device file
+# outputs: UUID on success
+# nothing on failure
+# returns: nothing
+getuuid()
+{
+ [ -z "$1" ] && die_error "getuuid needs an argument"
+ [ "${1%%/[hs]d?[0-9]}" != "${1}" ] && echo "$(blkid -s UUID -o value ${1})"
+}
+
+# taken from setup. slightly optimized. TODO: fix identation + can be improved more
+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 grep -qw $(echo $devpath /proc/mdstat | 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"
+}
+
+
+# taken from setup
+get_grub_map() {
+ rm /tmp/dev.map
+ $var_TARGET_DIR/sbin/grub --no-floppy --device-map /tmp/dev.map >/tmp/grub.log 2>&1 <<EOF
+quit
+EOF
+}
+
+
+# TODO: $1 is what??
+# taken from setup. slightly edited.
+mapdev() {
+ partition_flag=0
+ device_found=0
+ devs=$( grep -v fd /tmp/dev.map | 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" >&2
+ fi
+}
+
+# _mkfs() taken from setup code and slightly improved.
+# Create and mount filesystems in our destination system directory.
+#
+# args:
+# $1 domk: Whether to make the filesystem or use what is already there (yes/no)
+# $2 device: Device filesystem is on
+# $3 fstype: type of filesystem located at the device (or what to create)
+# $4 dest: Mounting location for the destination system
+# $5 mountpoint: Mount point inside the destination system, e.g. '/boot'
+
+# returns: 1 on failure
+_mkfs() {
+ local _domk=$1
+ local _device=$2
+ local _fstype=$3
+ local _dest=$4
+ local _mountpoint=$5
+
+ # we have two main cases: "swap" and everything else.
+ if [ "${_fstype}" = "swap" ]; then
+ swapoff ${_device} >/dev/null 2>&1
+ if [ "${_domk}" = "yes" ]; then
+ mkswap ${_device} >$LOG 2>&1 || show_warning "Error creating swap: mkswap ${_device}" && return 1
+ fi
+ swapon ${_device} >$LOG 2>&1 || show_warning "Error activating swap: swapon ${_device}" && return 1
+ else
+ # make sure the fstype is one we can handle
+ local knownfs=0
+ for fs in xfs jfs reiserfs ext2 ext3 vfat; do
+ [ "${_fstype}" = "${fs}" ] && knownfs=1 && break
+ done
+
+ [ $knownfs -eq 0 ] && show_warning "unknown fstype ${_fstype} for ${_device}" && return 1
+ # if we were tasked to create the filesystem, do so
+ if [ "${_domk}" = "yes" ]; then
+ local ret
+ case ${_fstype} in
+ xfs) mkfs.xfs -f ${_device} >$LOG 2>&1; ret=$? ;;
+ jfs) yes | mkfs.jfs ${_device} >$LOG 2>&1; ret=$? ;;
+ reiserfs) yes | mkreiserfs ${_device} >$LOG 2>&1; ret=$? ;;
+ ext2) mke2fs "${_device}" >$LOG 2>&1; ret=$? ;;
+ ext3) mke2fs -j ${_device} >$LOG 2>&1; ret=$? ;;
+ vfat) mkfs.vfat ${_device} >$LOG 2>&1; ret=$? ;;
+ # don't handle anything else here, we will error later
+ esac
+ [ $ret != 0 ] && show_warning "Error creating filesystem ${_fstype} on ${_device}" && return 1
+ sleep 2
+ fi
+ # create our mount directory
+ mkdir -p ${_dest}${_mountpoint}
+ # mount the bad boy
+ mount -t ${_fstype} ${_device} ${_dest}${_mountpoint} >$LOG 2>&1
+ [ $? != 0 ] && show_warning "Error mounting ${_dest}${_mountpoint}" && return 1
+ fi
+
+ # add to temp fstab
+ local _uuid="$(getuuid ${_device})"
+ if [ -n "${_uuid}" ]; then
+ _device="UUID=${_uuid}"
+ fi
+ echo -n "${_device} ${_mountpoint} ${_fstype} defaults 0 " >>/tmp/.fstab
+
+ if [ "${_fstype}" = "swap" ]; then
+ echo "0" >>/tmp/.fstab
+ else
+ echo "1" >>/tmp/.fstab
+ fi
+}
+
+
+# auto_fstab(). taken from setup
+# preprocess fstab file
+# comments out old fields and inserts new ones
+# according to partitioning/formatting stage
+#
+auto_fstab()
+{
+ if [ "$S_MKFS" = "1" -o "$S_MKFSAUTO" = "1" ]; then
+ if [ -f /tmp/.fstab ]; then
+ # comment out stray /dev entries
+ sed -i 's/^\/dev/#\/dev/g' $var_TARGET_DIR/etc/fstab
+ # append entries from new configuration
+ sort /tmp/.fstab >>$var_TARGET_DIR/etc/fstab
+ fi
+ fi
+}
diff --git a/src/core/libs/lib-misc.sh b/src/core/libs/lib-misc.sh
new file mode 100644
index 0000000..bc9b150
--- /dev/null
+++ b/src/core/libs/lib-misc.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+
+# run a process in the background, and log it's stdout and stderr to a specific logfile
+# $1 identifier
+# $2 command (will be eval'ed)
+# $3 logfile
+run_background ()
+{
+ [ -z "$1" ] && die_error "run_background: please specify an identifier to keep track of the command!"
+ [ -z "$2" ] && die_error "run_background needs a command to execute!"
+ [ -z "$3" ] && die_error "run_background needs a logfile to redirect output to!"
+
+ ( \
+ touch /tmp/$1-running
+ echo "$1 progress ..." > $3; \
+ echo >> $3; \
+ eval "$1" >>$3 2>&1
+ echo $? > /tmp/.$1-retcode
+ echo >> $3
+ rm -f /tmp/$1-running
+ ) &
+
+ sleep 2
+}
+
+
+# wait untill a process is done
+# $1 identifier
+wait_for ()
+{
+ [ -z "$1" ] && die_error "wait_for needs an identifier to known on which command to wait!"
+
+ while [ -f /tmp/$1-running ]
+ do
+ #TODO: follow_progress dialog mode = nonblocking (so check and sleep is good), cli mode (tail -f )= blocking? (so check is probably not needed as it will be done)
+ sleep 1
+ done
+
+ kill $(cat $ANSWER) #TODO: this may not work when mode = cli
+}
+
diff --git a/src/core/libs/lib-network.sh b/src/core/libs/lib-network.sh
new file mode 100644
index 0000000..93ba9cb
--- /dev/null
+++ b/src/core/libs/lib-network.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# auto_network(). taken from setup
+# configures network on host system according to installer
+# settings if user wishes to do so
+#
+auto_network()
+{
+ if [ $S_DHCP -ne 1 ]; then
+ sed -i "s#eth0=\"eth0#$INTERFACE=\"$INTERFACE#g" ${var_TARGET_DIR}/etc/rc.conf
+ sed -i "s# 192.168.0.2 # $IPADDR #g" ${var_TARGET_DIR}/etc/rc.conf
+ sed -i "s# 255.255.255.0 # $SUBNET #g" ${var_TARGET_DIR}/etc/rc.conf
+ sed -i "s# 192.168.0.255\"# $BROADCAST\"#g" ${var_TARGET_DIR}/etc/rc.conf
+ sed -i "s#eth0)#$INTERFACE)#g" ${var_TARGET_DIR}/etc/rc.conf
+ if [ "$GW" != "" ]; then
+ sed -i "s#gw 192.168.0.1#gw $GW#g" ${var_TARGET_DIR}/etc/rc.conf
+ sed -i "s#!gateway#gateway#g" ${var_TARGET_DIR}/etc/rc.conf
+ fi
+ echo "nameserver $DNS" >> ${var_TARGET_DIR}/etc/resolv.conf
+ else
+ sed -i "s#eth0=\"eth0.*#$INTERFACE=\"dhcp\"#g" ${var_TARGET_DIR}/etc/rc.conf
+ fi
+
+ if [ "$PROXY_HTTP" != "" ]; then
+ echo "export http_proxy=$PROXY_HTTP" >> ${var_TARGET_DIR}/etc/profile.d/proxy.sh;
+ chmod a+x ${var_TARGET_DIR}/etc/profile.d/proxy.sh
+ fi
+
+ if [ "$PROXY_FTP" != "" ]; then
+ echo "export ftp_proxy=$PROXY_FTP" >> ${var_TARGET_DIR}/etc/profile.d/proxy.sh;
+ chmod a+x ${var_TARGET_DIR}/etc/profile.d/proxy.sh
+ fi
+}
diff --git a/src/core/libs/lib-pacman.sh b/src/core/libs/lib-pacman.sh
new file mode 100644
index 0000000..4f64794
--- /dev/null
+++ b/src/core/libs/lib-pacman.sh
@@ -0,0 +1,177 @@
+#!/bin/sh
+
+# taken and slightly modified from the quickinst script.
+# don't know why one should need a static pacman because we already have a working one on the livecd.
+assure_pacman_static ()
+{
+ PACMAN_STATIC=
+ [ -f /tmp/usr/bin/pacman.static ] && PACMAN_STATIC=/tmp/usr/bin/pacman.static
+ [ -f /usr/bin/pacman.static ] && PACMAN_STATIC=/usr/bin/pacman.static
+ if [ "$PACMAN_STATIC" = "" ]; then
+ cd /tmp
+ if [ "$var_PKG_SOURCE_TYPE" = "ftp" ]; then
+ echo "Downloading pacman..."
+ wget $PKGARG/pacman*.pkg.tar.gz
+ if [ $? -gt 0 ]; then
+ echo "error: Download failed"
+ exit 1
+ fi
+ tar -xzf pacman*.pkg.tar.gz
+ elif [ "$var_PKG_SOURCE_TYPE" = "cd" ]; then
+ echo "Unpacking pacman..."
+ tar -xzf $PKGARG/pacman*.pkg.tar.gz
+ fi
+ fi
+ [ -f /tmp/usr/bin/pacman.static ] && PACMAN_STATIC=/tmp/usr/bin/pacman.static
+ if [ "$PACMAN_STATIC" = "" ]; then
+ echo "error: Cannot find the pacman.static binary!"
+ exit 1
+ fi
+}
+
+
+# taken from the quickinst script. cd/ftp code merged together
+target_write_pacman_conf ()
+{
+ PKGFILE=/tmp/packages.txt
+ echo "[core]" >/tmp/pacman.conf
+ if [ "$var_PKG_SOURCE_TYPE" = "ftp" ]
+ then
+ wget $PKG_SOURCE/packages.txt -O /tmp/packages.txt || die_error " Could not fetch package list from server"
+ echo "Server = $PKGARG" >>/tmp/pacman.conf
+ fi
+ if [ "$var_PKG_SOURCE_TYPE" = "cd" ]
+ then
+ [ -f $PKG_SOURCE/packages.txt ] || die_error "error: Could not find package list: $PKGFILE"
+ cp $PKG_SOURCE/packages.txt /tmp/packages.txt
+ echo "Server = file://$PKGARG" >>/tmp/pacman.conf
+ fi
+ mkdir -p $var_TARGET_DIR/var/cache/pacman/pkg /var/cache/pacman &>/dev/null
+ rm -f /var/cache/pacman/pkg &>/dev/null
+ [ "$var_PKG_SOURCE_TYPE" = "ftp" ] && ln -sf $var_TARGET_DIR/var/cache/pacman/pkg /var/cache/pacman/pkg &>/dev/null
+ [ "$var_PKG_SOURCE_TYPE" = "cd" ] && ln -sf $PKGARG /var/cache/pacman/pkg &>/dev/null
+}
+
+
+# target_prepare_pacman() taken from setup. modified a bit
+# configures pacman and syncs for the first time on destination system
+#
+# params: none
+# returns: 1 on error
+target_prepare_pacman() {
+ [ "$var_PKG_SOURCE_TYPE" = "cd" ] && local serverurl="${var_FILE_URL}"
+ [ "$var_PKG_SOURCE_TYPE" = "ftp" ] && local serverurl="${var_SYNC_URL}"
+
+ # Setup a pacman.conf in /tmp
+ cat << EOF > /tmp/pacman.conf
+[options]
+CacheDir = ${var_TARGET_DIR}/var/cache/pacman/pkg
+CacheDir = /src/core/pkg
+
+[core]
+Server = ${serverurl}
+EOF
+
+ # Set up the necessary directories for pacman use
+ [ ! -d "${var_TARGET_DIR}/var/cache/pacman/pkg" ] && mkdir -m 755 -p "${var_TARGET_DIR}/var/cache/pacman/pkg"
+ [ ! -d "${var_TARGET_DIR}/var/lib/pacman" ] && mkdir -m 755 -p "${var_TARGET_DIR}/var/lib/pacman"
+
+ notify "Refreshing package database..."
+ $PACMAN_TARGET -Sy >$LOG 2>&1 || return 1
+ return 0
+}
+
+
+# taken from quickinst. TODO: figure this one out
+pacman_what_is_this_for ()
+{
+ PKGLIST=
+ # fix pacman list!
+ sed -i -e 's/-i686//g' -e 's/-x86_64//g' $PKGFILE
+ for i in $(cat $PKGFILE | grep 'base/' | cut -d/ -f2); do
+ nm=${i%-*-*}
+ PKGLIST="$PKGLIST $nm"
+ done
+ ! [ -d $var_TARGET_DIR/var/lib/pacman ] && mkdir -p $var_TARGET_DIR/var/lib/pacman
+ ! [ -d /var/lib/pacman ] && mkdir -p /var/lib/pacman
+}
+
+
+
+# select_mirror(). taken from setup. TODO: get the UI code out of here
+# Prompt user for preferred mirror and set $var_SYNC_URL
+#
+# args: none
+# returns: nothing
+select_mirror() {
+ notify "Keep in mind ftp.archlinux.org is throttled.\nPlease select another mirror to get full download speed."
+ # FIXME: this regex doesn't honor commenting
+ MIRRORS=$(egrep -o '((ftp)|(http))://[^/]*' "${MIRRORLIST}" | sed 's|$| _|g')
+ _dia_DIALOG --menu "Select an FTP/HTTP mirror" 14 55 7 \
+ $MIRRORS \
+ "Custom" "_" 2>$ANSWER || return 1
+ local _server=$(cat $ANSWER)
+ if [ "${_server}" = "Custom" ]; then
+ _dia_DIALOG --inputbox "Enter the full URL to core repo." 8 65 \
+ "ftp://ftp.archlinux.org/core/os/i686" 2>$ANSWER || return 1
+ var_SYNC_URL=$(cat $ANSWER)
+ else
+ # Form the full URL for our mirror by grepping for the server name in
+ # our mirrorlist and pulling the full URL out. Substitute 'core' in
+ # for the repository name, and ensure that if it was listed twice we
+ # only return one line for the mirror.
+ var_SYNC_URL=$(egrep -o "${_server}.*" "${MIRRORLIST}" | sed 's/\$repo/core/g' | head -n1)
+ fi
+ echo "Using mirror: $var_SYNC_URL" >$LOG
+}
+
+# select_source(). taken from setup. TODO: decouple ui
+# displays installation source selection menu
+# and sets up relevant config files
+#
+# params: none
+# returns: nothing
+select_source()
+{
+ DIALOG --menu "Please select an installation source" 10 35 3 \
+ "1" "CD-ROM or OTHER SOURCE" \
+ "2" "FTP/HTTP" 2>$ANSWER
+
+ case $(cat $ANSWER) in
+ "1")
+ MODE="cd"
+ ;;
+ "2")
+ MODE="ftp"
+ ;;
+ esac
+
+ if [ "$MODE" = "cd" ]; then
+ TITLE="Arch Linux CDROM or OTHER SOURCE Installation"
+ DIALOG --msgbox "Packages included on this disk have been mounted to /src/core/pkg. If you wish to use your own packages from another source, manually mount them there." 0 0
+ if [ ! -d /src/core/pkg ]; then
+ DIALOG --msgbox "Package directory /src/core/pkg is missing!" 0 0
+ return 1
+ fi
+ echo "Using CDROM for package installation" >$LOG
+ else
+ TITLE="Arch Linux FTP/HTTP Installation"
+ DIALOG --msgbox "If you wish to load your ethernet modules manually, please do so now in another terminal." 12 65
+ while 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")
+ select_mirror ;;
+ *)
+ break ;;
+ esac
+ done
+ fi
+ S_SRC=1
+}
diff --git a/src/core/libs/lib-software.sh b/src/core/libs/lib-software.sh
new file mode 100644
index 0000000..95bc07a
--- /dev/null
+++ b/src/core/libs/lib-software.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+
+# run_mkinitcpio() taken from setup. adapted a lot
+# runs mkinitcpio on the target system, displays output
+run_mkinitcpio()
+{
+ target_special_fs on
+
+ run_background mkinitcpio "chroot $var_TARGET_DIR /sbin/mkinitcpio -p kernel26" /tmp/mkinitcpio.log
+ follow_progress "Rebuilding initcpio images ..." /tmp/mkinitcpio.log
+ wait_for mkinitcpio
+
+ target_special_fs off
+
+ # alert the user to fatal errors
+ [ $(cat /tmp/.mkinitcpio-retcode) -ne 0 ] && show_warning "MKINITCPIO FAILED - SYSTEM MAY NOT BOOT" "/tmp/mkinitcpio.log" text
+}
+
+
+# installpkg(). taken from setup. modified bigtime
+# performs package installation to the target system
+installpkg() {
+ notify "Package installation will begin now. You can watch the output in the progress window. Please be patient." 0 0
+ target_specialfs on
+ run_background pacman-installpkg "$PACMAN_TARGET -S $PACKAGES" /tmp/pacman.log
+ follow_progress " Installing... Please Wait " /tmp/pacman.log
+
+ wait_for pacman-installpkg
+
+ local _result=''
+ if [ $(cat /tmp/.pacman-retcode) -ne 0 ]; then
+ _result="Installation Failed (see errors below)"
+ echo -e "\nPackage Installation FAILED." >>/tmp/pacman.log
+ else
+ _result="Installation Complete"
+ echo -e "\nPackage Installation Complete." >>/tmp/pacman.log
+ fi
+ rm /tmp/.pacman-retcode
+
+ show_warning "$_result" "/tmp/pacman.log" text || return 1
+
+ target_specialfs off
+
+ sync
+}
+
+# auto_locale(). taken from setup
+# enable glibc locales from rc.conf and build initial locale DB
+auto_locale()
+{
+ for i in $(grep "^LOCALE" ${var_TARGET_DIR}/etc/rc.conf | sed -e 's/.*="//g' -e's/\..*//g'); do
+ sed -i -e "s/^#$i/$i/g" ${var_TARGET_DIR}/etc/locale.gen
+ done
+ DIALOG --infobox "Generating glibc base locales..." 4 40
+ chroot ${var_TARGET_DIR} locale-gen >/dev/null
+}
diff --git a/src/core/libs/lib-ui.sh b/src/core/libs/lib-ui.sh
new file mode 100644
index 0000000..7fc611f
--- /dev/null
+++ b/src/core/libs/lib-ui.sh
@@ -0,0 +1,246 @@
+#!/bin/sh
+# TODO: lot's of implementation work still open in this library. especially the dialog stuff
+
+
+# Taken from setup. we store dialog output in a file. TODO: can't we do this with variables?
+ANSWER="/tmp/.setup"
+
+
+
+### Functions that your code can use. Cli/dialog mode is fully transparant. This library takes care of it ###
+
+
+# ask the user a password. return is stored in $PASSWORD or $<TYPE>_PASSWORD
+# $1 type (optional. eg 'svn', 'ssh').
+ask_password ()
+{
+ [ "$var_UI_TYPE" = dia ] && { _dia_ask_password "$@" ; return $? ; }
+ [ "$var_UI_TYPE" = cli ] && { _cli_ask_password "$@" ; return $? ; }
+}
+
+
+# ask a yes/no question.
+# $1 question
+# returns 0 if response is yes/y (case insensitive). 1 otherwise
+# TODO: support for default answer
+ask_yesno ()
+{
+ [ -z "$1" ] && die_error "ask_yesno needs a question!"
+ [ "$var_UI_TYPE" = dia ] && { _dia_ask_yesno "$@" ; return $? ; }
+ [ "$var_UI_TYPE" = cli ] && { _cli_ask_yesno "$@" ; return $? ; }
+}
+
+
+# ask for a string.
+# $1 question
+# echo's the string the user gave.
+# returns 1 if the user cancelled, 0 otherwise
+ask_string ()
+{
+ [ -z "$1" ] && die_error "ask_string needs a question!"
+ [ "$var_UI_TYPE" = dia ] && { _dia_ask_string "$@" ; return $? ; }
+ [ "$var_UI_TYPE" = cli ] && { _cli_ask_string "$@" ; return $? ; }
+}
+
+
+# TODO: we should have a wrapper around this function that keeps trying until the user entered a valid numeric?
+# ask for a number.
+# $1 question
+# $2 lower limit (optional)
+# $3 upper limit (optional)
+# echo's the number the user said
+# returns 1 if the user cancelled or did not enter a numeric, 0 otherwise
+ask_number ()
+{
+ [ -z "$1" ] && die_error "ask_number needs a question!"
+ [ -n "$2" ] && [[ $2 = *[^0-9]* ]] && die_error "ask_number \$2 must be a number! not $2"
+ [ -n "$3" ] && [[ $3 = *[^0-9]* ]] && die_error "ask_number \$3 must be a number! not $3"
+ [ "$var_UI_TYPE" = dia ] && { _dia_ask_number "$1" "$2" "$3" ; return $? ; }
+ [ "$var_UI_TYPE" = cli ] && { _cli_ask_number "$1" "$2" "$3" ; return $? ; }
+}
+
+
+# ask the user to choose something
+# TODO: exact implementation, which arguments etc?
+ask_option ()
+{
+ [ "$var_UI_TYPE" = dia ] && { _dia_ask_option "$@" ; return $? ; }
+ [ "$var_UI_TYPE" = cli ] && { _cli_ask_option "$@" ; return $? ; }
+}
+
+
+# follow the progress of something by showing it's log, updating real-time
+# $1 title
+# $2 logfile
+follow_progress ()
+{
+ [ -z "$1" ] && die_error "follow_progress needs a title!"
+ [ -z "$2" ] && die_error "follow_progress needs a logfile to follow!"
+ [ "$var_UI_TYPE" = dia ] && { _dia_follow_progress "$1" "$2" ; return $? ; }
+ [ "$var_UI_TYPE" = cli ] && { _cli_follow_progress "$1" "$2" ; return $? ; }
+}
+
+
+# taken from setup
+printk()
+{
+ case $1 in
+ "on") echo 4 >/proc/sys/kernel/printk ;;
+ "off") echo 0 >/proc/sys/kernel/printk ;;
+ esac
+}
+
+
+
+
+
+### Internal functions, supposed to be only used internally in this library ###
+
+
+# DIALOG() taken from setup
+# an el-cheapo dialog wrapper
+#
+# parameters: see dialog(1)
+# returns: whatever dialog did
+_dia_DIALOG()
+{
+ dialog --backtitle "$TITLE" --aspect 15 "$@"
+ return $?
+}
+
+
+# geteditor(). taken from original setup code. prepended dia_ because power users just export $EDITOR on the cmdline.
+# prompts the user to choose an editor
+# sets EDITOR global variable
+#
+# TODO: clean this up
+_dia_get_editor() {
+ _dia_DIALOG --menu "Select a Text Editor to Use" 10 35 3 \
+ "1" "nano (easier)" \
+ "2" "vi" 2>$ANSWER
+ case $(cat $ANSWER) in
+ "1") EDITOR="nano" ;;
+ "2") EDITOR="vi" ;;
+ *) EDITOR="nano" ;;
+ esac
+}
+
+# TODO: pass disks as argument to decouple backend logic
+# Get a list of available disks for use in the "Available disks" dialogs. This
+# will print the disks as follows, getting size info from hdparm:
+# /dev/sda: 640133 MBytes (640 GB)
+# /dev/sdb: 640135 MBytes (640 GB)
+_dia_getavaildisks()
+{
+ # NOTE: to test as non-root, stick in a 'sudo' before the hdparm call
+ for i in $(finddisks); do echo -n "$i: "; hdparm -I $i | grep -F '1000*1000' | sed "s/.*1000:[ \t]*\(.*\)/\1/"; echo "\n"; done
+}
+
+
+# taken from setup code. edited to echo the choice, not perform it
+# TODO: also an ugly function
+_dia_ask_bootloader()
+{
+ _dia_DIALOG --colors --menu "Which bootloader would you like to use? Grub is the Arch default.\n\n" \
+ 10 65 2 \
+ "GRUB" "Use the GRUB bootloader (default)" \
+ "None" "\Zb\Z1Warning\Z0\ZB: you must install your own bootloader!" 2>$ANSWER
+ cat $ANSWER
+}
+
+
+_dia_follow_progress ()
+{
+ title=$1
+ logfile=$2
+ _dia_DIALOG --title "$1" --no-kill --tailboxbg "$2" 18 70 2>$ANSWER
+}
+
+
+_dia_ask_yesno ()
+{
+ dialog --yesno "$1" 10 55 # returns 0 for yes, 1 for no
+}
+
+
+_cli_ask_password ()
+{
+ if [ -n "$1" ]
+ then
+ type_l=`tr '[:upper:]' '[:lower:]' <<< $1`
+ type_u=`tr '[:lower:]' '[:upper:]' <<< $1`
+ else
+ type_l=
+ type_u=
+ fi
+
+ echo -n "Enter your $type_l password: "
+ stty -echo
+ [ -n "$type_u" ] && read ${type_u}_PASSWORD
+ [ -z "$type_u" ] && read PASSWORD
+ stty echo
+ echo
+}
+
+_cli_ask_yesno ()
+{
+ echo -n "$1 (y/n): "
+ read answer
+ answer=`tr '[:upper:]' '[:lower:]' <<< $answer`
+ if [ "$answer" = y -o "$answer" = yes ]
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+
+_cli_ask_string ()
+{
+ echo -n "$@: "
+ read answ
+ echo "$answ"
+ [ -z "$answ" ] && return 1
+ return 0
+}
+
+
+_cli_ask_number ()
+{
+ #TODO: i'm not entirely sure this works perfectly. what if user doesnt give anything or wants to abort?
+ while true
+ do
+ str="$1"
+ [ -n "$2" ] && str2="min $2"
+ [ -n "$3" ] && str2="$str2 max $3"
+ [ -n "$str2" ] && str="$str ( $str2 )"
+ echo "$str"
+ read answ
+ if [[ $answ = *[^0-9]* ]]
+ then
+ show_warning "$answ is not a number! try again."
+ else
+ break
+ fi
+ done
+ echo "$answ"
+ [ -z "$answ" ] && return 1
+ return 0
+}
+
+
+_cli_ask_option ()
+{
+ die_error "_cli_ask_option Not yet implemented"
+}
+
+
+_cli_follow_progress ()
+{
+ title=$1
+ logfile=$2
+ echo "Title: $1"
+ tail -f $2
+}
+
diff --git a/src/core/procedures/base b/src/core/procedures/base
new file mode 100644
index 0000000..215af0a
--- /dev/null
+++ b/src/core/procedures/base
@@ -0,0 +1,143 @@
+#!/bin/bash
+
+var_DEFAULTFS="/boot:32:ext2:+ swap:256:swap /:7500:ext3 /home:*:ext3"
+var_TARGET_DIR="/mnt"
+var_RUNTIME_PACKAGES=
+var_PKG_FILE=/home/arch/fifa/runtime/package-list
+var_UI_TYPE="cli" # set to cli or dia for dialog
+
+###### Phases ( can be overridden by more specific procedures) ######
+
+phase_preparation ()
+{
+ execute worker select_source
+ execute worker runtime_packages
+}
+
+
+phase_basics ()
+{
+ execute worker set_clock
+ execute worker prepare_disks
+}
+
+
+phase_system ()
+{
+ execute worker package_list
+ execute worker install_packages
+ execute worker auto_fstab #TODO: exact names of these 3
+ execute worker auto_network
+ execute worker auto_locale
+ execute worker configure_system
+ execute worker mkinitcpio
+ execute worker locales
+ execute worker install_bootloader
+}
+
+
+phase_finish ()
+{
+ true
+}
+
+
+
+###### Workers ( can be overridden by more specific procedures) ######
+worker_select_source ()
+{
+ var_PKG_SOURCE_TYPE='cd'
+ var_FILE_URL="file:///src/core/pkg"
+ var_MIRRORLIST="/etc/pacman.d/mirrorlist"
+ # if you override to use ftp (or ask user and he chooses ftp) don't forget to configure the network and to select_mirrors
+}
+
+
+worker_runtime_packages ()
+{
+ for pkg in $var_RUNTIME_PACKAGES
+ do
+ $PACMAN -Sy --noconfirm --needed $pkg
+ done
+}
+
+
+worker_set_clock ()
+{
+ HARDWARECLOCK=utc
+ TIMEZONE=`tzselect`
+ HWCLOCK_PARAMS=" --utc"
+ if [ "$TIMEZONE" != "" -a -e "/usr/share/zoneinfo/$TIMEZONE" ]
+ then
+ cp "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
+ fi
+ /sbin/hwclock --hctosys $HWCLOCK_PARAMS --noadjfile
+ #TODO: user must set date/time and store it
+}
+
+
+worker_prepare_disks ()
+{
+ partition # use lib-archboot function by default
+ # in official installer: autoprepare or diy first partitions, then mountpoints
+}
+
+
+# Put the list of packages to be installed in $var_PKG_FILE
+worker_package_list ()
+{
+ #TODO: sensible list of packages
+ true
+}
+
+
+worker_install_packages ()
+{
+ target_special_fs on
+ target_prepare_pacman
+ [ ! -f $var_PKG_FILE ] && die_error "No package file available!"
+ PKGLIST=`cat $var_PKG_FILE`
+ #TODO: what if $var_PKG_FILE is empty? we should die_error because that's probably not what the user wants.. or can it? will pacman complain?
+ $PACMAN_TARGET -Sy $PKGLIST || die_error "Package installation FAILED."
+ target_special_fs off
+}
+
+
+worker_auto_fstab ()
+{
+}
+
+
+worker_auto_network ()
+{
+}
+
+
+worker_auto_locale ()
+{
+
+}
+
+
+worker_configure_system ()
+{
+ #TODO: what to do here?
+ true
+}
+
+
+worker_mkinitcpio ()
+{
+}
+
+
+worker_locales ()
+{
+}
+
+
+worker_install_bootlader ()
+{
+ #TODO: ask which disk, install grub on it
+ true
+}
diff --git a/src/core/procedures/interactive-DRAFT b/src/core/procedures/interactive-DRAFT
new file mode 100644
index 0000000..145b32d
--- /dev/null
+++ b/src/core/procedures/interactive-DRAFT
@@ -0,0 +1,842 @@
+#!/bin/sh
+
+TARGET_DIR="/mnt"
+EDITOR=
+
+
+# clock
+HARDWARECLOCK=
+TIMEZONE=
+
+# partitions
+PART_ROOT=
+
+# default filesystem specs (the + is bootable flag)
+# <mountpoint>:<partsize>:<fstype>[:+]
+DEFAULTFS="/boot:32:ext2:+ swap:256:swap /:7500:ext3 /home:*:ext3"
+
+
+
+start_process ()
+{
+ #####################
+ ## begin execution ##
+
+ # 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_GRUB=0 # TODO: kill this - if using grub
+ S_BOOT="" # bootloader installed (set to loader name instead of 1)
+
+ var_UI_TYPE=dia
+
+ notify "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."
+
+ while true
+ do
+ mainmenu
+ done
+
+}
+
+
+phase_preparation ()
+{
+ #TODO: when does grub device map happen in official installer?
+ execute worker runtime_packages
+ notify "Generating GRUB device map...\nThis could take a while.\n\n Please be patient."
+ get_grub_map
+}
+
+mainmenu()
+{
+ if [ -n "$NEXTITEM" ]; then
+ DEFAULT="--default-item $NEXTITEM"
+ else
+ DEFAULT=""
+ fi
+ DIALOG $DEFAULT --title " MAIN MENU " \
+ --menu "Use the UP and DOWN arrows to navigate menus. Use TAB to switch between buttons and ENTER to select." 16 55 8 \
+ "0" "Select Source" \
+ "1" "Set Clock" \
+ "2" "Prepare Hard Drive" \
+ "3" "Select Packages" \
+ "4" "Install Packages" \
+ "5" "Configure System" \
+ "6" "Install Bootloader" \
+ "7" "Exit Install" 2>$ANSWER
+ NEXTITEM="$(cat $ANSWER)"
+ case $(cat $ANSWER) in
+ "0")
+ select_source ;;
+ "1")
+ set_clock ;;
+ "2")
+ prepare_harddrive ;;
+ "3")
+ select_packages ;;
+ "4")
+ installpkg ;;
+ "5")
+ configure_system ;;
+ "6")
+ install_bootloader ;;
+ "7")
+ 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 && exit 0
+ ;;
+ esac
+}
+
+partition() {
+ if [ "$S_MKFSAUTO" = "1" ]; then
+ notify "You have already prepared your filesystems with Auto-prepare" 0 0
+ return 0
+ fi
+
+ _umountall
+
+ # Select disk to partition
+ DISCS=$(finddisks _)
+ DISCS="$DISCS OTHER - DONE +"
+ DIALOG --msgbox "Available Disks:\n\n$(_getavaildisks)\n" 0 0
+ DISC=""
+ while true; do
+ # Prompt the user with a list of known disks
+ DIALOG --menu "Select the disk you want to partition (select DONE when finished)" 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
+ # Leave our loop if the user is done partitioning
+ [ "$DISC" = "DONE" ] && break
+ # 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 ttell 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
+ done
+ S_PART=1
+}
+
+
+configure_system()
+{
+ ## PREPROCESSING ##
+ # only done on first invocation of configure_system
+ if [ $S_CONFIG -eq 0 ]; then
+
+ # /etc/pacman.d/mirrorlist
+ # add installer-selected mirror to the top of the mirrorlist
+ if [ "$MODE" = "ftp" -a "${SYNC_URL}" != "" ]; then
+ awk "BEGIN { printf(\"# Mirror used during installation\nServer = "${SYNC_URL}"\n\n\") } 1 " "${TARGET_DIR}/etc/pacman.d/mirrorlist"
+ fi
+
+ # /etc/rc.conf
+ # insert timezone and utc info
+ sed -i -e "s/^TIMEZONE=.*/TIMEZONE=\"$TIMEZONE\"/g" \
+ -e "s/^HARDWARECLOCK=.*/HARDWARECLOCK=\"$HARDWARECLOCK\"/g" \
+ ${TARGET_DIR}/etc/rc.conf
+ fi
+
+ ## END PREPROCESS ##
+
+ [ "$EDITOR" ] || geteditor
+ FILE=""
+
+ # main menu loop
+ while true; do
+ if [ -n "$FILE" ]; then
+ DEFAULT="--default-item $FILE"
+ else
+ DEFAULT=""
+ fi
+
+ DIALOG $DEFAULT --menu "Configuration" 17 70 10 \
+ "/etc/rc.conf" "System Config" \
+ "/etc/fstab" "Filesystem Mountpoints" \
+ "/etc/mkinitcpio.conf" "Initramfs Config" \
+ "/etc/modprobe.conf" "Kernel Modules" \
+ "/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" \
+ "/etc/pacman.d/mirrorlist" "Pacman Mirror List" \
+ "Root-Password" "Set the root password" \
+ "Return" "Return to Main Menu" 2>$ANSWER || FILE="Return"
+ FILE="$(cat $ANSWER)"
+ if [ "$FILE" = "Return" -o -z "$FILE" ]; then # exit
+ break
+ elif [ "$FILE" = "Root-Password" ]; then # non-file
+ while true; do
+ chroot ${TARGET_DIR} passwd root && break
+ done
+ else #regular file
+ $EDITOR ${TARGET_DIR}${FILE}
+ fi
+ done
+
+ ## POSTPROCESSING ##
+
+ # /etc/initcpio.conf
+ #
+ run_mkinitcpio
+
+ # /etc/locale.gen
+ #
+ chroot ${TARGET_DIR} locale-gen
+
+ ## END POSTPROCESSING ##
+
+ S_CONFIG=1
+}
+
+
+prepare_harddrive()
+{
+ S_MKFSAUTO=0
+ S_MKFS=0
+ DONE=0
+ NEXTITEM=""
+ while [ "$DONE" = "0" ]; do
+ if [ -n "$NEXTITEM" ]; then
+ DEFAULT="--default-item $NEXTITEM"
+ else
+ DEFAULT=""
+ fi
+ DIALOG $DEFAULT --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")
+ autoprepare ;;
+ "2")
+ partition ;;
+ "3")
+ PARTFINISH=""
+ mountpoints ;;
+ *)
+ DONE=1 ;;
+ esac
+ done
+ NEXTITEM="1"
+}
+
+
+# set_clock()
+# prompts user to set hardware clock and timezone
+#
+# params: none
+# returns: 1 on failure
+set_clock()
+{
+ # utc or local?
+ DIALOG --menu "Is your hardware clock in UTC or local time?" 10 50 2 \
+ "UTC" " " \
+ "local" " " \
+ 2>$ANSWER || return 1
+ HARDWARECLOCK=$(cat $ANSWER)
+
+ # timezone?
+ tzselect > $ANSWER || return 1
+ TIMEZONE=$(cat $ANSWER)
+
+ # set system clock from hwclock - stolen from rc.sysinit
+ local HWCLOCK_PARAMS=""
+ if [ "$HARDWARECLOCK" = "UTC" ]; then
+ HWCLOCK_PARAMS="$HWCLOCK_PARAMS --utc"
+ else
+ HWCLOCK_PARAMS="$HWCLOCK_PARAMS --localtime"
+ fi
+ if [ "$TIMEZONE" != "" -a -e "/usr/share/zoneinfo/$TIMEZONE" ]; then
+ /bin/rm -f /etc/localtime
+ /bin/cp "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
+ fi
+ /sbin/hwclock --hctosys $HWCLOCK_PARAMS --noadjfile
+
+ # display and ask to set date/time
+ dialog --calendar "Set the date.\nUse <TAB> to navigate and arrow keys to change values." 0 0 0 0 0 2> $ANSWER || return 1
+ local _date="$(cat $ANSWER)"
+ dialog --timebox "Set the time.\nUse <TAB> to navigate and up/down to change values." 0 0 2> $ANSWER || return 1
+ local _time="$(cat $ANSWER)"
+ echo "date: $_date time: $_time" >$LOG
+
+ # save the time
+ # DD/MM/YYYY hh:mm:ss -> YYYY-MM-DD hh:mm:ss
+ local _datetime="$(echo "$_date" "$_time" | sed 's#\(..\)/\(..\)/\(....\) \(..\):\(..\):\(..\)#\3-\2-\1 \4:\5:\6#g')"
+ echo "setting date to: $_datetime" >$LOG
+ date -s "$_datetime" 2>&1 >$LOG
+ /sbin/hwclock --systohc $HWCLOCK_PARAMS --noadjfile
+
+ S_CLOCK=1
+}
+
+[ $S_SELECT -eq 0 ] && install_pkg && S_INSTALL=1 # user must first select, then install
+# automagic time!
+# any automatic configuration should go here
+notify "Writing base configuration..."
+auto_fstab
+auto_network
+auto_locale
+
+autoprepare()
+{
+ DISCS=$(finddisks)
+ if [ $(echo $DISCS | wc -w) -gt 1 ]; then
+ DIALOG --msgbox "Available Disks:\n\n$(_getavaildisks)\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=""
+ # get just the disk size in 1000*1000 MB
+ DISC_SIZE=$(hdparm -I /dev/sda | grep -F '1000*1000' | sed "s/^.*:[ \t]*\([0-9]*\) MBytes.*$/\1/")
+ 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 (MB) of your /boot partition. Minimum value is 16.\n\nDisk space left: $DISC_SIZE MB" 8 65 "32" 2>$ANSWER || return 1
+ BOOT_PART_SIZE="$(cat $ANSWER)"
+ if [ "$BOOT_PART_SIZE" = "" ]; then
+ DIALOG --msgbox "ERROR: You have entered an invalid 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 too large 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 (MB) of your swap partition. Minimum value is > 0.\n\nDisk space left: $DISC_SIZE MB" 8 65 "256" 2>$ANSWER || return 1
+ SWAP_PART_SIZE=$(cat $ANSWER)
+ if [ "$SWAP_PART_SIZE" = "" -o "$SWAP_PART_SIZE" -le "0" ]; then
+ DIALOG --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0
+ else
+ if [ "$SWAP_PART_SIZE" -ge "$DISC_SIZE" ]; then
+ DIALOG --msgbox "ERROR: You have entered a too large 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 (MB) of your / partition. The /home partition will use the remaining space.\n\nDisk space left: $DISC_SIZE MB" 8 65 "7500" 2>$ANSWER || return 1
+ ROOT_PART_SIZE=$(cat $ANSWER)
+ if [ "$ROOT_PART_SIZE" = "" -o "$ROOT_PART_SIZE" -le "0" ]; then
+ DIALOG --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0
+ else
+ if [ "$ROOT_PART_SIZE" -ge "$DISC_SIZE" ]; then
+ DIALOG --msgbox "ERROR: You have entered a too large size, please enter again." 0 0
+ else
+ DIALOG --yesno "$(($DISC_SIZE-$ROOT_PART_SIZE)) MB will be used for your /home partition. Is this OK?" 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. Is this OK?" 0 0 && CHOSEN_FS=1
+ done
+ SET_DEFAULTFS=1
+ done
+
+ DIALOG --defaultno --yesno "$DISC will be COMPLETELY ERASED! Are you absolutely sure?" 0 0 \
+ || return 1
+
+ DEVICE=$DISC
+ FSSPECS=$(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")
+ sfdisk_input=""
+
+ # we assume a /dev/hdX format (or /dev/sdX)
+ PART_ROOT="${DEVICE}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 "$TARGET_DIR" ]; then
+ DIALOG --msgbox "Destination directory '$TARGET_DIR' is not valid" 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
+
+ rm -f /tmp/.fstab
+
+ _umountall
+
+ # 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
+ printk 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" "$TARGET_DIR" "$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" "$TARGET_DIR" "$mountpoint" || return 1
+ fi
+ part=$(($part + 1))
+ done
+
+ DIALOG --msgbox "Auto-prepare was successful" 0 0
+ S_MKFSAUTO=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
+ 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$(_getavaildisks)\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")"
+ if [ "$PART" != "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)" 18 0 && PARTFINISH="DONE"
+ done
+
+ _umountall
+
+ 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 ${TARGET_DIR}${MP}
+ if [ "$DOMKFS" = "yes" ]; then
+ if [ "$FSTYPE" = "swap" ]; then
+ DIALOG --infobox "Creating and activating swapspace on $PART" 0 0
+ else
+ DIALOG --infobox "Creating $FSTYPE on $PART, mounting to ${TARGET_DIR}${MP}" 0 0
+ fi
+ _mkfs yes $PART $FSTYPE $TARGET_DIR $MP || return 1
+ else
+ if [ "$FSTYPE" = "swap" ]; then
+ DIALOG --infobox "Activating swapspace on $PART" 0 0
+ else
+ DIALOG --infobox "Mounting $PART to ${TARGET_DIR}${MP}" 0 0
+ fi
+ _mkfs no $PART $FSTYPE $TARGET_DIR $MP || return 1
+ fi
+ sleep 1
+ done
+
+ DIALOG --msgbox "Partitions were successfully mounted." 0 0
+ S_MKFS=1
+}
+
+# select_packages()
+# prompts the user to select packages to install
+#
+# params: none
+# returns: 1 on error
+select_packages() {
+ # step dependencies
+ if [ $S_SRC -eq 0 ]; then
+ DIALOG --msgbox "You must select an installation source!" 0 0
+ return 1
+ fi
+
+ # if selection has been done before, warn about loss of input
+ # and let the user exit gracefully
+ if [ $S_SELECT -ne 0 ]; then
+ DIALOG --yesno "WARNING: Running this stage again will result in the loss of previous package selections.\n\nDo you wish to continue?" 10 50 || return 1
+ fi
+
+ 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 for each category, allowing you to fine-tune.\n\n" 15 70
+
+ # set up our install location if necessary and sync up
+ # so we can get package lists
+ prepare_pacman
+ if [ $? -ne 0 ]; then
+ DIALOG --msgbox "Pacman preparation failed! Check $LOG for errors." 6 60
+ return 1
+ fi
+
+ # show group listing for group selection
+ local _catlist="base ^ ON"
+ for i in $($PACMAN -Sg | sed "s/^base$/ /g"); do
+ _catlist="${_catlist} ${i} - OFF"
+ done
+
+ DIALOG --checklist "Select Package Categories\nDO NOT deselect BASE unless you know what you're doing!" 19 55 12 $_catlist 2>$ANSWER || return 1
+ _catlist="$(cat $ANSWER)"
+
+ # assemble a list of packages with groups, marking pre-selected ones
+ # <package> <group> <selected>
+ local _pkgtmp="$($PACMAN -Sl core | awk '{print $2}')"
+ local _pkglist=''
+
+ $PACMAN -Si $_pkgtmp | \
+ awk '/^Name/{ printf("%s ",$3) } /^Group/{ print $3 }' > $ANSWER
+ while read pkgname pkgcat; do
+ # check if this package is in a selected group
+ # slightly ugly but sorting later requires newlines in the variable
+ if [ "${_catlist/"\"$pkgcat\""/XXXX}" != "${_catlist}" ]; then
+ _pkglist="$(echo -e "${_pkglist}\n${pkgname} ${pkgcat} ON")"
+ else
+ _pkglist="$(echo -e "${_pkglist}\n${pkgname} ${pkgcat} OFF")"
+ fi
+ done < $ANSWER
+
+ # sort by category
+ _pkglist="$(echo "$_pkglist" | sort -f -k 2)"
+
+ DIALOG --checklist "Select Packages To Install." 19 60 12 $_pkglist 2>$ANSWER || return 1
+ PACKAGES="$(cat $ANSWER)"
+ S_SELECT=1
+}
+
+
+# donetwork()
+# Hand-hold through setting up networking
+#
+# args: none
+# returns: 1 on failure
+donetwork() {
+ INTERFACE=""
+ S_DHCP=""
+ local ifaces
+ ifaces=$(ifconfig -a |grep "Link encap:Ethernet"|sed 's/ \+Link encap:Ethernet \+HWaddr \+/ /g')
+
+ if [ "$ifaces" = "" ]; then
+ DIALOG --msgbox "Cannot find any ethernet interfaces. This usually means udev was\nunable to load the module and you must do it yourself. Switch to\nanother VT, load the appropriate module, and run this step again." 18 70
+ return 1
+ fi
+
+ DIALOG --nocancel --ok-label "Select" --menu "Select a network interface" 14 55 7 $ifaces 2>$ANSWER
+ case $? in
+ 0) INTERFACE=$(cat $ANSWER) ;;
+ *) return 1 ;;
+ esac
+
+ 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
+ if [ $? -ne 0 ]; then
+ DIALOG --msgbox "Failed to run dhcpcd. See $LOG for details." 0 0
+ return 1
+ fi
+ 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" 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
+ echo "running: ifconfig $INTERFACE $IPADDR netmask $SUBNET broadcast $BROADCAST up" >$LOG
+ 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
+ DIALOG --msgbox "The network is configured." 0 0
+ S_NET=1
+}
+
+dogrub() {
+ get_grub_map
+ local grubmenu="$TARGET_DIR/boot/grub/menu.lst"
+ if [ ! -f $grubmenu ]; then
+ DIALOG --msgbox "Error: Couldn't find $grubmenu. 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)
+ local _rootpart="${PART_ROOT}"
+ local _uuid="$(getuuid ${PART_ROOT})"
+ # attempt to use a UUID if the root device has one
+ if [ -n "${_uuid}" ]; then
+ _rootpart="/dev/disk/by-uuid/${_uuid}"
+ fi
+ # look for a separately-mounted /boot partition
+ bootdev=$(mount | grep $TARGET_DIR/boot | cut -d' ' -f 1)
+ if [ "$grubdev" != "" -o "$bootdev" != "" ]; then
+ subdir=
+ if [ "$bootdev" != "" ]; then
+ grubdev=$(mapdev $bootdev)
+ else
+ subdir="/boot"
+ fi
+ # keep the file from being completely bogus
+ if [ "$grubdev" = "DEVICE NOT FOUND" ]; then
+ DIALOG --msgbox "Your root boot device could not be autodetected by setup. Ensure you adjust the 'root (hd0,0)' line in your GRUB config accordingly." 0 0
+ grubdev="(hd0,0)"
+ fi
+ # remove default entries by truncating file at our little tag (#-*)
+ sed -i -e '/#-\*/q'
+ cat >>$grubmenu <<EOF
+
+# (0) Arch Linux
+title Arch Linux
+root $grubdev
+kernel $subdir/vmlinuz26 root=${_rootpart} ro
+initrd $subdir/kernel26.img
+
+# (1) Arch Linux
+title Arch Linux Fallback
+root $grubdev
+kernel $subdir/vmlinuz26 root=${_rootpart} ro
+initrd $subdir/kernel26-fallback.img
+
+# (2) Windows
+#title Windows
+#rootnoverify (hd0,0)
+#makeactive
+#chainloader +1
+EOF
+ 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 $grubmenu
+
+ 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 and not a partition)." 14 55 7 $DEVS 2>$ANSWER || return 1
+ ROOTDEV=$(cat $ANSWER)
+ DIALOG --infobox "Installing the GRUB bootloader..." 0 0
+ cp -a $TARGET_DIR/usr/lib/grub/i386-pc/* $TARGET_DIR/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 $TARGET_DIR/boot > /dev/null 2>&1
+ /usr/sbin/xfs_freeze -f $TARGET_DIR/ > /dev/null 2>&1
+ fi
+ # look for a separately-mounted /boot partition
+ bootpart=$(mount | grep $TARGET_DIR/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
+ if [ "$bootpart" = "DEVICE NOT FOUND" -o "$bootdev" = "DEVICE NOT FOUND" ]; then
+ DIALOG --msgbox "GRUB root and setup devices could not be auto-located. You will need to manually run the GRUB shell to install a bootloader." 0 0
+ return 1
+ fi
+ $TARGET_DIR/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 $TARGET_DIR/boot > /dev/null 2>&1
+ /usr/sbin/xfs_freeze -u $TARGET_DIR/ > /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
+}
+
+
+ # exit if network wasn't configured in installer
+ if [ $S_NET -eq 0 ]; then
+ return 1
+ fi
+
+ ask_yesno "Do you want to use the network settings from the installer in rc.conf and resolv.conf?\n\nIf you used Proxy settings, they will be written to /etc/profile.d/proxy.sh" || return 1
+
+ if [ $S_DHCP -ne 1 ]; then
+ auto_network
+fi
+ \ No newline at end of file
diff --git a/src/core/procedures/quickinst-DRAFT b/src/core/procedures/quickinst-DRAFT
new file mode 100644
index 0000000..9e92c03
--- /dev/null
+++ b/src/core/procedures/quickinst-DRAFT
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+quickinst_finished ()
+{
+echo
+echo "Package installation complete."
+echo
+echo "Please install a bootloader. Edit the appropriate config file for"
+echo "your loader, and chroot into your system to install it into the"
+echo "boot sector:"
+echo " # mount -o bind /dev $DESTDIR/dev"
+echo " # mount -t proc none $DESTDIR/proc"
+echo " # mount -t sysfs none $DESTDIR/sys"
+echo " # chroot $DESTDIR /bin/bash"
+echo
+echo "For GRUB:"
+echo " # install-grub /dev/sda /dev/sdaX (replace with your boot partition)"
+echo " (or install manually by invoking the GRUB shell)"
+echo "HINT XFS FILESYSTEM:"
+echo "If you have created xfs filesystems, freeze them before and unfreeze them after"
+echo "installing grub (outside the chroot):"
+echo "- freeze:"
+echo " # xfs_freeze -f $DESTDIR/boot"
+echo " # xfs_freeze -f $DESTDIR/"
+echo "- unfreeze:"
+echo " # xfs_freeze -u $DESTDIR/boot"
+echo " # xfs_freeze -u $DESTDIR/"
+echo
+echo "For LILO:"
+echo " # lilo"
+echo
+echo "Next step, initramfs setup:"
+echo "Edit your /etc/mkinitcpio.conf and /etc/mkinitcpio.d/kernel26-fallback.conf"
+echo "to fit your needs. After that run:"
+echo "# mkinitcpio -p kernel26"
+echo
+echo "Then exit your chroot shell, edit $DESTDIR/etc/fstab and"
+echo "$DESTDIR/etc/rc.conf, and reboot!"
+echo
+}