summaryrefslogtreecommitdiff
path: root/src/core/libs
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/libs')
-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
6 files changed, 840 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
+}
+