#!/bin/bash setterm -powersave off setterm -blank 0 if [ -r ./restore-image-lib.sh ]; then . ./restore-image-lib.sh elif [ -r /usr/lib/restore-image-lib.sh ]; then . /usr/lib/restore-image-lib.sh fi export PATH="/sbin:/bin:/usr/sbin:/usr/bin" mnt_dir="/tmp/mnt" restore_media="/tmp/media" images_dir="$restore_media/images" images="$images_dir/list" images_config="$images_dir/config" image="" win32_part_dev= win32_part_type= win32_part_new_size= function read_config() { if [ -r "$images_config" ]; then . $images_config fi } function image_list() { list=$(cat $images | awk -F',' \ '{ print $1 " " $2 " " $4 }') echo $list } function image_file() { country="$1" file=$(grep ^$country $images | awk -F',' '{ print $3 }') echo $file } function welcome() { while true; do clear msg="\n Welcome to $TITLE\n\ \nThe following images were found, select one:\n " opcao=$(dialog --backtitle "$BACKTITLE" --title "$TITLE" \ --stdout --radiolist "$msg" 0 0 0 \ $(image_list)) if [ "$?" != "0" ]; then _yesno "\nInterrupt installation?\n " if [ "$?" = "0" ]; then _shutdown fi else if [ -z "$opcao" ]; then continue else image=$(image_file $opcao) break fi fi done # disable kernel messages in the console echo "1 4 1 7" > /proc/sys/kernel/printk } function install_warning() { if [ -n "${win32_part_dev}" ]; then warn_msg="Windows installation detected.\nWe will set it up as dual boot. \ You may lose some data.\nPlease backup before proceeding." else warn_msg="WARNING: This process will erase all data in this machine, \ do you want to continue?" fi clear _yesno "\n$warn_msg\n" if [ "$?" != "0" ]; then _shutdown fi } function detect_root() { inst_source_dev=$(awk "\$2 == \"$restore_media\" { print \$1 }" /proc/mounts | sed -e 's/[0-9]$//') inst_source_dev=${inst_source_dev#/dev/} devices=$(grep "^ .*[^0-9]$" < /proc/partitions | grep -v ${inst_source_dev} | awk '$3 > '$MIN_DISKSIZE' { print $4,$3 }') if [ -z "${devices}" ]; then exit 1 fi devs_found=$(($(echo $devices | wc -w)/2)) root_data=$(detect_win32 ${inst_source_dev}) if [ -z "${root_data}" ]; then if [ "$devs_found" -gt "1" ]; then if [ -n "${inst_source_dev}" ]; then opcao=$(dialog --backtitle "$BACKTITLE" --title "$TITLE" --stdout --menu 'Choose one of the detected devices to restore to (check the blocks size column first):' 8 50 0 $devices ) if [ "$?" != "0" ]; then _yesno "\nInterrupt installation?\n " if [ "$?" = "0" ]; then _shutdown fi else root_data=${opcao} fi fi else root_data=$(echo ${devices} | cut -d ' ' -f 1) fi fi echo ${root_data} } function detect_win32() { # from detect_root() skip_dev=${1} # win32 detection won't handle complex layouts if [ $(fdisk -l | grep "^/dev/" | grep -v ${skip_dev} | wc -l) -gt 1 ]; then exit fi # get the last created windows partition information set -f device=$(fdisk -l | grep "^/dev/" | grep -v ${skip_dev} | grep -e "FAT\|NTFS\|HPFS" | tail -1 | sed 's/ .*$//') set +f if [ -z "${device}" ]; then exit fi # it might be needed, for safety device_type=$(blkid -o value -s TYPE ${device}) modprobe ${device_type} # df for that partition mount ${device} /mnt size=$(df ${device} | tail -1) umount /mnt # its diskspace used=$(echo ${size} | awk '{ print $3 }') left=$(echo ${size} | awk '{ print $4 }') avail=$((${left}/2)) if [ ! ${avail} -lt ${MIN_DISKSIZE} ]; then win32_part_dev=${device} win32_part_type=${device_type} # our install takes half of 'left' win32_part_new_size=$((${used}+${avail})) dev=${win32_part_dev#/dev/} disk=${dev%[0-9]} number=${dev#[a-w][a-w][a-w]} let number++ echo ${disk}${number} ${win32_part_dev} ${win32_part_type} ${win32_part_new_size} fi } function resize_win32() { device=${1} device_type=${2} new_win32_size=${3} dialog --backtitle "$BACKTITLE" --title "$TITLE" --infobox "\nResizing Windows partition...\n" 4 55 dev=${device#/dev/} disk=${dev%[0-9]} win32_number=${dev#[a-w][a-w][a-w]} case ${device_type} in vfat) device_id=b ;; ntfs) device_id=7 ;; hpfs) device_id=87 ;; esac # wrapper around libdrakx by blino diskdrake-resize ${device} ${device_type} $((${new_win32_size}*2)) &>/dev/null # we need some free sector here, rebuilding layout fdisk /dev/${disk} &>/dev/null <<EOF d n p ${win32_number} +${new_win32_size}K t ${device_id} a ${win32_number} w EOF # adds linux partition to the end of the working disk fdisk /dev/${disk} &>/dev/null <<EOF n p $((${win32_number}+1)) +${MIN_DISKSIZE}K t $((${win32_number}+1)) 83 w EOF } function detect_device() { dialog --backtitle "$BACKTITLE" --title "$TITLE" --infobox "\nTrying to detect your root partition and disk...\n" 4 55 root_data=$(detect_root) if [ -z "${root_data}" ]; then _msgbox "\nError writing image: disk device not detected.\n" # so that netbooks using USB sticks as disks can retry (like Gdium) welcome root_data=$(detect_root) fi set ${root_data} root=$1 win32_part_dev=$2 win32_part_type=$3 win32_part_new_size=$4 } function write_image() { if [ -n "${win32_part_dev}" ]; then resize_win32 ${win32_part_dev} ${win32_part_type} ${win32_part_new_size} fi image=$(cat $images_dir/list | cut -d ',' -f 3) extension=${image/*./} imagesize=$(ls -l $images_dir/$image | awk '{ print $5 }') case $extension in gz) uncomp=zcat total=$(gzip -l $images_dir/$image | tail -n 1 | awk '{ print $2 }') ;; bz2) uncomp=bzcat total=$((imagesize * 3)) ;; *) uncomp=cat total=$imagesize ;; esac skipstart=/bin/true if [ -n "$win32_part_dev" ]; then skipstart='dd of=/dev/null bs=1 count=32256' fi # the actual dumping command, from image to disk ${uncomp} ${images_dir}/${image} | (${skipstart} &>/dev/null; dd bs=4M of=/dev/${root} >/tmp/backup.out 2>&1>>/tmp/log) & sleep 3 pid=$(ps ax | grep 'dd bs=4M of' | grep -v grep | awk '{ print $1 }') while [ true ]; do ps | grep -q $pid if [ $? -eq 0 ]; then /bin/kill -SIGUSR1 $pid complete=$(tail -n 1 /tmp/backup.out | awk '{ print $1 }') echo $((complete*100/total)) sleep 1 else break fi done | dialog --backtitle "$BACKTITLE" --title "$TITLE" --gauge "\nWriting image..." 8 45 in=$(tail -n 3 /tmp/backup.out | grep 'in$' | cut -d' ' -f1) out=$(tail -n 3 /tmp/backup.out | grep 'out$' | cut -d' ' -f1) if [ x"$in" != x"$out" ]; then _msgbox "\nError writing image!\n" sleep 24h fi # Now re-read the partition table because 'dd' might have changed it sfdisk -R /dev/${root} } function grub_setup() { root=${1} grub_dir=${2} # install the bootloader grub <<EOF device (hd0) /dev/${root%[0-9]} root (hd0,1) setup (hd0) quit EOF # change the partition order and boot timeout accordingly sed -i 's/(hd0,0)/(hd0,1)/g;/^timeout/s/$/0/' ${grub_dir}/menu.lst # dualboot configuration for grub cat >> ${grub_dir}/menu.lst <<EOF title Microsoft Windows root (hd0,0) makeactive rootnoverify(hd0,0) chainloader +1 EOF } function expand_fs() { if [ -z "$win32_part_dev" ]; then if [ -n "$MAIN_PART_NUMBER" ]; then part_number=$MAIN_PART_NUMBER else part_number=1 fi root=${root%[0-9]}$part_number fi filesystem_type=$(dumpe2fs -h /dev/${root} 2>/dev/null| grep "Filesystem OS type" | awk '{ print $4 }') if [ "${filesystem_type}" = "Linux" ]; then dialog --backtitle "$BACKTITLE" --title "$TITLE" --infobox "Finishing Install... Expanding ${root}" 3 40 disk=/dev/${root%[0-9]} main_part=/dev/${root} # FIXME: absurdly dirty hack main_part_num=${root:3} swap_part_num=$((main_part_num+1)) swap_part=${disk}${swap_part_num} main_part_sectors= if [ -n "$SWAP_BLOCKS" ]; then if [ -n "$EXPAND_FS" ]; then total_blocks=$(sfdisk -s $disk) main_part_blocks=$((total_blocks-SWAP_BLOCKS)) main_part_sectors=$((main_part_blocks*2)) else main_part_sectors=$(sfdisk -d $disk | perl -lne 'm|^'$main_part'\b.*,\s*size\s*=\s*(\d+)\b| and print($1), exit') fi fi if [ -n "$SWAP_BLOCKS" ]; then parted $disk -- mkpartfs primary linux-swap ${main_part_sectors}s -1s yes mkswap -L swap $swap_part fi if [ -n "$EXPAND_FS" ]; then e2fsck -fy $main_part fdisk $disk << EOF d $main_part_num n p $main_part_num a $main_part_num w EOF sfdisk -R $disk e2fsck -fy $main_part resize2fs $main_part fi mkdir -p $mnt_dir mount $main_part $mnt_dir grub_dir="$mnt_dir/boot/grub" if [ -d "$grub_dir" ]; then echo "(hd0) $disk" > "$grub_dir/device.map" if [ -n "$win32_part_dev" ]; then grub_setup ${root} ${grub_dir} fi fi if [ -n "$MKINITRD" ]; then mount -t sysfs none "$mnt_dir/sys" mount -t proc none "$mnt_dir/proc" echo > /proc/sys/kernel/modprobe # rescue's modprobe does not handle modprobe -q and aliases chroot $mnt_dir bootloader-config --action rebuild-initrds umount "$mnt_dir/sys" umount "$mnt_dir/proc" fi umount $mnt_dir fi } # installation steps welcome read_config detect_device install_warning write_image expand_fs # all done! _msgbox "\nInstallation process finished.\nPress ENTER to shutdown.\n " _shutdown