diff options
author | Dieter Plaetinck <dieter@plaetinck.be> | 2008-11-02 22:04:36 +0100 |
---|---|---|
committer | Dieter Plaetinck <dieter@plaetinck.be> | 2008-11-02 22:04:36 +0100 |
commit | 4019db7a540d6dfcef6431cfc11ca748595e2ca1 (patch) | |
tree | fc47df27708360c71699609f80d0b732b28412d8 /src/core/libs | |
parent | c8a41a8f2afdb46e9da3bc9a677210b74b82eaab (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/libs')
-rw-r--r-- | src/core/libs/lib-blockdevices-filesystems.sh | 285 | ||||
-rw-r--r-- | src/core/libs/lib-misc.sh | 42 | ||||
-rw-r--r-- | src/core/libs/lib-network.sh | 33 | ||||
-rw-r--r-- | src/core/libs/lib-pacman.sh | 177 | ||||
-rw-r--r-- | src/core/libs/lib-software.sh | 57 | ||||
-rw-r--r-- | src/core/libs/lib-ui.sh | 246 |
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 +} + |