#!/bin/sh

EXPR=/bin/expr
MOUNT=/bin/mount
MKSWAP=/bin/mkswap
SWAPON=/bin/swapon

find_dev_by_type () {
    [ -z "$2" ] && \
        panic "find_dev_by_type called with too few arguments: ($1, $2)"
    local dev=""
    case "$2" in
        swap)
            dev=$(fdisk -l $1 | grep -i 'Linux Swap' | gawk '{print $1}')
            ;;
        ntfs)
            dev=$(fdisk -l $1 | grep -i 'NTFS' | gawk '{print $1}')
            ;;
        vfat)
            dev=$(fdisk -l $1 | grep -v 'NTFS' | grep -i 'FAT' | gawk '{print $1}')
            ;;
        ext2)
            dev=$(fdisk -l $1 | grep -i 'Linux$' | gawk '{print $1}')
            ;;
        *)
            panic "unknown filesystem searched: $2"
            ;;
    esac    
    echo $dev
}

find_fs () {
  # echoes all partitions found by given type
    [ -z "$1" ] && \
        panic "find_fs called with too few arguments: $1"
    local fstype=$1
    local found="n"
    local s=""
    local d=""
  # IDE (old):
    for d in a b c d e f g h i j k l; do
        if [ -e /dev/hd${d} ]; then
            s="$s $(find_dev_by_type /dev/hd${d} $fstype)"
            found="y"
        fi
    done
  # SCSI/USB
    for d in a b c d e f g h i j k l; do
        if [ -e /dev/sd${d} ]; then
            s="$s $(find_dev_by_type /dev/hd${d} $fstype)"
            found="y"
        fi
    done
  # virtual:
    for d in a b c d e f g h i j k l; do
        if [ -e /dev/vd${d} ]; then
            s="$s $(find_dev_by_type /dev/vd${d} $fstype)"
            found="y"
        fi
    done
    if [ "$found" = "y" ]; then 
        echo "$s"
        return 0
    else
        return -1
    fi
}

find_swap () {
    find_fs swap
}

find_ntfs () {
    find_fs ntfs
}

find_vfat () {
    find_fs vfat
}

find_ext2 () {
    find_fs ext2
}

find_part_by_label  ()
{
  # returns true/false only
    [ -z "$1" ] && \
        panic "find_part_by_label called with too few arguments: $1"
    local label=$1
    local plabel=""
    local found="n"
    local p=""

    if [ -e /dev/disk/by-label/$1 ]; then
        return 0
    fi
    for p in /dev/disk/by-id/*part* /dev/disk/by-path/*part*; do
        plabel=$(tune2fs -l $p 2>/dev/null| gawk '/Filesystem volume name:/ {print $4}')
        if [ "$label" = "$plabel" ]; then
            found="y"
            break;
        fi
    done
    if [ "$found" = "y" ]; then 
        return 0
    else
        return 1
    fi
}

kill_ext_part () {
    [ -z "$1" ] && \
        panic "kill_ext_part called with too few arguments: $1"
    local hd0dev=$1
    local i=""
    
  # get id of existing ext part
    extpart=$(sfdisk -l $hd0dev -uS 2>/dev/null| \
        gawk '/Extended/ {match($1,/^\/dev\/.*[a-z]([0-9]+)$/,a);\
                               print a[1];}')
    
  # 
    if [ -n "$extpart" ];then
        echo "DESTROYING extended partition ${extpart} as requested in 10 seconds!"
        echo "Last chance to reset!!"
        for i in 10 9 8 7 6 5 4 3 2 1 0; do
            echo -n "${i}..."
            sleep 1
        done
        fdisk $hd0dev <<EOT
d
$extpart
w
EOT
    fi
}

kill_swap_parts () {
    [ -z "$1" ] && \
        panic "kill_swap_parts called with too few arguments: $1"
    local hd0dev=$1
    local i=""
    
  # get ids of existing swap parts, largest id first
    local swapparts=$(sfdisk -l $hd0dev -uS 2>/dev/null| \
        gawk '/^\// {
                match($1,/^\/dev\/.*[a-z]([0-9]+)$/,a);
                if($2=="*") {
                        if($6=="82") print a[1];
                    } else {
                        if($5=="82") print a[1];
                    }
                    }' | sort -rn )
    
  # 
    if [ -n "$swapparts" ];then
        echo "DESTROYING all SWAP partitions (${swapparts}) as requested in 10 seconds!"
        echo "Last chance to reset!!"
        for i in 10 9 8 7 6 5 4 3 2 1 0; do
            echo -n "${i}..."
            sleep 1
        done
        for i in $swapparts; do
            fdisk $hd0dev <<EOT
d
$i
w
EOT
        done
    fi
}

kill_ext2fs_parts () {
    [ -z "$1" ] && \
        panic "kill_ext2fs_parts called with too few arguments: $1"
    local hd0dev=$1
    local i=""
    
  # get ids of existing ext2 parts, largest id first
    local ext2parts=$(sfdisk -l $hd0dev -uS 2>/dev/null| \
        gawk '/^\// {
                match($1,/^\/dev\/.*[a-z]([0-9]+)$/,a);
                if($2=="*") {
                        if($6=="83") print a[1];
                    } else {
                        if($5=="83") print a[1];
                    }
                    }' | sort -rn )
    
  # 
    if [ -n "$ext2parts" ];then
        echo "DESTROYING all UNIKLU EXT2FS partitions (${ext2parts}) as requested in 10 seconds!"
        echo "Last chance to reset!!"
        for i in 10 9 8 7 6 5 4 3 2 1 0; do
            echo -n "${i}..."
            sleep 1
        done
        for i in $ext2parts; do
            l=$(tune2fs -l $hd0dev$i 2>/dev/null| gawk '/Filesystem volume name:/ {print $4}')
            for L in $LABELS; do
                if [ "$l" = "$L" ]; then
                    fdisk $hd0dev <<EOT
d
$i
w
EOT
                fi
            done
        done
    fi
}

kill_all_parts () {
    [ -z "$1" ] && \
        panic "kill_all_parts called with too few arguments: $1"
    local hd0dev=$1
    echo "DESTROYING partition table on $hd0dev as requested in 10 seconds!"
    echo "Last chance to reset!!"
    for i in 10 9 8 7 6 5 4 3 2 1 0; do
        echo -n "${i}..."
        sleep 1
    done
    fdisk $hd0dev <<EOT
o
w
EOT
}

format () {
    [ -z "$3" ] && \
        panic "format called with too few arguments: $1 $2 $3"
    FSTYPE=$1
    FSLABEL=$2
    PART=$3
    if [ "$FSTYPE" = "ext2" -o  "$FSTYPE" = "ext3" -o "$FSTYPE" = "ext4" -o "$FSTYPE" = "ntfs" -o "$FSTYPE" = "vfat"  ]; then
        FORMAT=mkfs.$FSTYPE
        MKFSFAILED=""
        $FORMAT -L $FSLABEL $PART || MKFSFAILED="yes"
        if [ "$MKFSFAILED" = "yes" ]; then
            sleep 5
            partprobe
            _log_msg "retry formatting ...\n"
            MKFSFAILED=""
            $FORMAT -L $FSLABEL $PART || MKFSFAILED="yes"
            if [ "$MKFSFAILED" = "yes" ]; then
                sleep 5
                partprobe
                _log_msg "retry formatting ...\n"
                MKFSFAILED=""
                $FORMAT -L $FSLABEL $PART || MKFSFAILED="yes"
                if [ "$MKFSFAILED" = "yes" ]; then
                    panic "mkfs failed three times?"
                    .echo "retry once more ...\n"
                    $FORMAT -L $FSLABEL $PART || MKFSFAILED="yes"
                fi
            fi
        fi
    elif [ "$FSTYPE" = "swap" ]; then
        FORMAT="mkswap"
        $FORMAT -L $FSLABEL $PART
    fi
  # let udev scan for new filesystem labels
    /sbin/udevadm trigger
    if [ -n "$break" ]; then
        panic "after $FORMAT"
    fi
}

find_hd0 () {
  # determine bios drive 0x80 via grub:
    grub1 --no-curses >/tmp/hd0 <<EOT
geometry (hd0)
quit
EOT
  local hd0dev=$(gawk '/drive 0x80/ {print $12}' /tmp/hd0)
  if [ -z "${hd0dev}" ]; then
      panic "could not determine BIOS drive 0x80! reset now or risc damage!"
  else
      echo $hd0dev
  fi
}

auto_partition () {
    [ -z "$1" ] && \
        panic "auto_partition called with too few arguments: $1"

    TARGET=$1
    
    P1SIZE=0
    P2SIZE=0
    P3SIZE=0
    P4SIZE=0
    P5SIZE=0
    P6SIZE=0
    P7SIZE=0
    
    hd0dev=$(find_hd0)
    _log_msg "found ${hd0dev} as BIOS drive 0x80."
    
    echo initialize_part_if_necessary
    initialize_part_if_necessary $hd0dev
    echo get_part_sizes
    SECTORSIZE=0
    SECTORNUMBER=0
    USEDPARTS=0
    eval $(get_part_sizes $hd0dev)

    echo check_or_create_ext_part
    EXTPART=0
    EXTPART_LASTSECTOR=0
    check_or_create_ext_part $hd0dev
    echo get_ext_part_sectors
    LASTPART=0
    LASTSECTOR=0
    EXTPART_FIRSTSECTOR=0
    eval $(get_ext_part_sectors $hd0dev)

  # get remaining sectors at end of ext. partition:
    echo ${EXPR} $EXTPART_LASTSECTOR - $LASTSECTOR - 1 
    REMSECTORS=$(${EXPR} $EXTPART_LASTSECTOR - $LASTSECTOR - 1 )
  # in bytes:
    echo ${EXPR} $REMSECTORS \* $SECTORSIZE 
    REMBYTES=$(${EXPR} $REMSECTORS \* $SECTORSIZE )

  # MINSIZE, MAXSIZE, SWAPSIZE, BOOTSIZE are in MB from here on
  # CMD line parameters are GB with decimals, so use bc -l !!
    if [ "$TARGET" = "install" ]; then
  # determine needed sizes
        ALLMINSIZE=0
        ALLMAXSIZE=0
        if  [ -n "$PART1MINSIZE" ]; then
            PART1MINSIZE=$(echo $PART1MINSIZE \* 1024 | bc -l) 
            PART1MINSIZE=${PART1MINSIZE%%.*}
            PART1MAXSIZE=$(echo $PART1MAXSIZE \* 1024 | bc -l) 
            PART1MAXSIZE=${PART1MAXSIZE%%.*}
            ALLMINSIZE=$(${EXPR} $ALLMINSIZE + $PART1MINSIZE  )
            ALLMAXSIZE=$(${EXPR} $ALLMAXSIZE + $PART1MAXSIZE  )
        fi
        if  [ -n "$PART2MINSIZE" ]; then
            PART2MINSIZE=$(echo $PART2MINSIZE \* 1024 | bc -l) 
            PART2MINSIZE=${PART2MINSIZE%%.*}
            PART2MAXSIZE=$(echo $PART2MAXSIZE \* 1024 | bc -l) 
            PART2MAXSIZE=${PART2MAXSIZE%%.*}
            ALLMINSIZE=$(${EXPR} $ALLMINSIZE + $PART2MINSIZE  )
            ALLMAXSIZE=$(${EXPR} $ALLMAXSIZE + $PART2MAXSIZE  )
        fi
        if  [ -n "$PART3MINSIZE" ]; then
            PART3MINSIZE=$(echo $PART3MINSIZE \* 1024 | bc -l) 
            PART3MINSIZE=${PART3MINSIZE%%.*}
            PART3MAXSIZE=$(echo $PART3MAXSIZE \* 1024 | bc -l) 
            PART3MAXSIZE=${PART3MAXSIZE%%.*}
            ALLMINSIZE=$(${EXPR} $ALLMINSIZE + $PART3MINSIZE  )
            ALLMAXSIZE=$(${EXPR} $ALLMAXSIZE + $PART3MAXSIZE  )
        fi
        if  [ -n "$PART4MINSIZE" ]; then
            PART4MINSIZE=$(echo $PART4MINSIZE \* 1024 | bc -l) 
            PART4MINSIZE=${PART4MINSIZE%%.*}
            PART4MAXSIZE=$(echo $PART4MAXSIZE \* 1024 | bc -l) 
            PART4MAXSIZE=${PART4MAXSIZE%%.*}
            ALLMINSIZE=$(${EXPR} $ALLMINSIZE + $PART4MINSIZE  )
            ALLMAXSIZE=$(${EXPR} $ALLMAXSIZE + $PART4MAXSIZE  )
        fi
        if  [ -n "$PART5MINSIZE" ]; then
            PART5MINSIZE=$(echo $PART5MINSIZE \* 1024 | bc -l) 
            PART5MINSIZE=${PART5MINSIZE%%.*}
            PART5MAXSIZE=$(echo $PART5MAXSIZE \* 1024 | bc -l) 
            PART5MAXSIZE=${PART5MAXSIZE%%.*}
            ALLMINSIZE=$(${EXPR} $ALLMINSIZE + $PART5MINSIZE  )
            ALLMAXSIZE=$(${EXPR} $ALLMAXSIZE + $PART5MAXSIZE  )
        fi
        if  [ -n "$PART6MINSIZE" ]; then
            PART6MINSIZE=$(echo $PART6MINSIZE \* 1024 | bc -l) 
            PART6MINSIZE=${PART6MINSIZE%%.*}
            PART6MAXSIZE=$(echo $PART6MAXSIZE \* 1024 | bc -l) 
            PART6MAXSIZE=${PART6MAXSIZE%%.*}
            ALLMINSIZE=$(${EXPR} $ALLMINSIZE + $PART6MINSIZE  )
            ALLMAXSIZE=$(${EXPR} $ALLMAXSIZE + $PART6MAXSIZE  )
        fi
        if  [ -n "$PART7MINSIZE" ]; then
            PART7MINSIZE=$(echo $PART7MINSIZE \* 1024 | bc -l) 
            PART7MINSIZE=${PART7MINSIZE%%.*}
            PART7MAXSIZE=$(echo $PART7MAXSIZE \* 1024 | bc -l) 
            PART7MAXSIZE=${PART7MAXSIZE%%.*}
            ALLMINSIZE=$(${EXPR} $ALLMINSIZE + $PART7MINSIZE  )
            ALLMAXSIZE=$(${EXPR} $ALLMAXSIZE + $PART7MAXSIZE  )
        fi


        if [ "$(${EXPR} $REMBYTES \< \( $ALLMINSIZE \* 1024 \* 1024 \) )" = "1" ]; then
            echo "EXTPART_FIRSTSECTOR: $EXTPART_FIRSTSECTOR"
            echo "EXTPART_LASTSECTOR:  $EXTPART_LASTSECTOR"
            echo "LASTSECTOR:          $LASTSECTOR"
            echo "LASTPART:            $LASTPART"
            echo "REMSECTORS:          $REMSECTORS"
            echo "REMBYTES:            $REMBYTES"
            echo "SECTORSIZE:          $SECTORSIZE"
            panic "not enough space: $REMBYTES, needed: $ALLMINSIZE"
        fi

        if [ "$(${EXPR} $REMBYTES \> \( $ALLMAXSIZE \* 1024 \* 1024 \) )" = "1" ]; then
            echo "enough space even for maximum configuration"
            P1SIZE=$(${EXPR} \( $PART1MAXSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            if [ -n "$PART2MAXSIZE" ]; then
                P2SIZE=$(${EXPR} \( $PART2MAXSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART3MAXSIZE" ]; then
                P3SIZE=$(${EXPR} \( $PART3MAXSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART4MAXSIZE" ]; then
                P4SIZE=$(${EXPR} \( $PART4MAXSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART5MAXSIZE" ]; then
                P5SIZE=$(${EXPR} \( $PART5MAXSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART6MAXSIZE" ]; then
                P6SIZE=$(${EXPR} \( $PART6MAXSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART7MAXSIZE" ]; then
                P7SIZE=$(${EXPR} \( $PART7MAXSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
        else
            P1SIZE=$(${EXPR} \( $PART1MINSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            if [ -n "$PART2MINSIZE" ]; then
                P2SIZE=$(${EXPR} \( $PART2MINSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART3MINSIZE" ]; then
                P3SIZE=$(${EXPR} \( $PART3MINSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART4MINSIZE" ]; then
                P4SIZE=$(${EXPR} \( $PART4MINSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART5MINSIZE" ]; then
                P5SIZE=$(${EXPR} \( $PART5MINSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART6MINSIZE" ]; then
                P6SIZE=$(${EXPR} \( $PART6MINSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
            if [ -n "$PART7MINSIZE" ]; then
                P7SIZE=$(${EXPR} \( $PART7MINSIZE \* 1024 \* 1024 \) / $SECTORSIZE + 1 )
            fi
        fi

        P1START=$(${EXPR} $LASTSECTOR + 1 ) 
        P1PART=$(${EXPR} $LASTPART + 1 )
        if [ "$P2SIZE" -gt 0 ]; then
            P2START=$(${EXPR} $LASTSECTOR + 1 + $P1SIZE )
            P2PART=$(${EXPR} $LASTPART + 2 )
            if [ "$P3SIZE" -gt 0 ]; then
                P3START=$(${EXPR} $LASTSECTOR + 1 + $P1SIZE  + $P2SIZE )
                P3PART=$(${EXPR} $LASTPART + 3 )
                if [ "$P4SIZE" -gt 0 ]; then
                    P4START=$(${EXPR} $LASTSECTOR + 1 + $P1SIZE  + $P2SIZE + $P3SIZE )
                    P4PART=$(${EXPR} $LASTPART + 4 )
                    if [ "$P5SIZE" -gt 0 ]; then
                        P5START=$(${EXPR} $LASTSECTOR + 1 + $P1SIZE  + $P2SIZE + $P3SIZE + $P4SIZE )
                        P5PART=$(${EXPR} $LASTPART + 5 )
                        if [ "$P6SIZE" -gt 0 ]; then
                            P6START=$(${EXPR} $LASTSECTOR + 1 + $P1SIZE  + $P2SIZE + $P3SIZE + $P4SIZE + $P5SIZE )
                            P6PART=$(${EXPR} $LASTPART + 6 )
                            if [ "$P7SIZE" -gt 0 ]; then
                                P7START=$(${EXPR} $LASTSECTOR + 1 + $P1SIZE  + $P2SIZE + $P3SIZE + $P4SIZE + $P5SIZE + $P6SIZE )
                                P7PART=$(${EXPR} $LASTPART + 7 )
                            fi
                        fi
                    fi
                fi
            fi
        fi


  # write existing partitions into sfdisk script
        sfdisk -d $hd0dev -uS 2>/dev/null >  /tmp/sfdisk.script
  # append our 2 partitions to sfdisk script
        echo "${hd0dev}$P1PART : start= $P1START, size= $P1SIZE, Id= $PART1PTYPE" >> /tmp/sfdisk.script
        _log_msg "will use partition $P1PART ($PART1PTYPE) with $P1SIZE sectors as $PART1FSTYPE for $PART1MOUNT file system\n"
        if  [ "$P2SIZE" -gt 0  ]; then
            echo "${hd0dev}$P2PART : start= $P2START, size= $P2SIZE, Id= $PART2PTYPE" >> /tmp/sfdisk.script
            _log_msg "will use partition $P2PART ($PART2PTYPE) with $P2SIZE sectors as $PART2FSTYPE for $PART2MOUNT file system\n"
            if  [ "$P3SIZE" -gt 0  ]; then
                echo "${hd0dev}$P3PART : start= $P3START, size= $P3SIZE, Id= $PART3PTYPE" >> /tmp/sfdisk.script
                _log_msg "will use partition $P3PART ($PART3PTYPE) with $P3SIZE sectors as $PART3FSTYPE for $PART3MOUNT file system\n"
                if  [ "$P4SIZE" -gt 0  ]; then
                    echo "${hd0dev}$P4PART : start= $P4START, size= $P4SIZE, Id= $PART4PTYPE" >> /tmp/sfdisk.script
                    _log_msg "will use partition $P4PART ($PART4PTYPE) with $P4SIZE sectors as $PART4FSTYPE for $PART4MOUNT file system\n"
                    if  [ "$P5SIZE" -gt 0  ]; then
                        echo "${hd0dev}$P5PART : start= $P5START, size= $P5SIZE, Id= $PART5PTYPE" >> /tmp/sfdisk.script
                        _log_msg "will use partition $P5PART ($PART5PTYPE) with $P5SIZE sectors as $PART5FSTYPE for $PART5MOUNT file system\n"
                        if  [ "$P6SIZE" -gt 0  ]; then
                            echo "${hd0dev}$P6PART : start= $P6START, size= $P6SIZE, Id= $PART6PTYPE" >> /tmp/sfdisk.script
                            _log_msg "will use partition $P6PART ($PART6PTYPE) with $P6SIZE sectors as $PART6FSTYPE for $PART6MOUNT file system\n"
                            if  [ "$P7SIZE" -gt 0  ]; then
                                echo "${hd0dev}$P7PART : start= $P7START, size= $P7SIZE, Id= $PART7PTYPE" >> /tmp/sfdisk.script
                                _log_msg "will use partition $P7PART ($PART7PTYPE) with $P7SIZE sectors as $PART7FSTYPE for $PART7MOUNT file system\n"
                            fi
                        fi
                    fi
                fi
            fi
        fi
        

  # debug:
        if [ -n "$break" ]; then
            echo "USEDPARTS:  ${USEDPARTS}"
            echo "NOTEMPTY:   ${NOTEMPTY}"
            echo "EXTPART:    ${EXTPART}"
            echo "LASTPART:   ${LASTPART}"
            echo "LASTSECTOR: ${LASTSECTOR}"
            echo "REMSECTORS: ${REMSECTORS}"
            echo "REMBYTES:   ${REMBYTES}"
            echo "SECTORSIZE: ${SECTORSIZE}"
            panic "about to apply /tmp/sfdisk.script to $hd0dev"
        fi

  # ensure disk is offline:
        swapoff -a
        /bin/umount /target
  # backup old table
        sfdisk -d $hd0dev > /tmp/hd0.old

  # install new partition table, good luck ;-)
        sfdisk --force $hd0dev < /tmp/sfdisk.script

  #force partition table reread
        partprobe
        sleep 5
        partprobe
        if [ -n "$break" ]; then
            panic "after partprobe"
        fi

        _log_msg "now formatting ...\n"

        if [ "$TARGET" = "install" ]; then
            echo "proc /proc proc nodev,noexec,nosuid 0 0" > /tmp/fstab
            format $PART1FSTYPE $PART1LABEL ${hd0dev}$P1PART
            echo "LABEL=$PART1LABEL  $PART1MOUNT  $PART1FSTYPE  $PART1FSOPTS 0 1" >> /tmp/fstab
            if  [ "$P2SIZE" -gt 0  ]; then
                format $PART2FSTYPE $PART2LABEL ${hd0dev}$P2PART
                echo "LABEL=$PART2LABEL  $PART2MOUNT  $PART2FSTYPE  $PART2FSOPTS 0 2" >> /tmp/fstab
                if  [ "$P3SIZE" -gt 0  ]; then
                    format $PART3FSTYPE $PART3LABEL ${hd0dev}$P3PART
                    echo "LABEL=$PART3LABEL  $PART3MOUNT  $PART3FSTYPE  $PART3FSOPTS 0 2" >> /tmp/fstab
                    if  [ "$P4SIZE" -gt 0  ]; then
                        format $PART4FSTYPE $PART4LABEL ${hd0dev}$P4PART
                        echo "LABEL=$PART4LABEL  $PART4MOUNT  $PART4FSTYPE  $PART4FSOPTS 0 2" >> /tmp/fstab
                        if  [ "$P5SIZE" -gt 0  ]; then
                            format $PART5FSTYPE $PART5LABEL ${hd0dev}$P5PART
                            echo "LABEL=$PART5LABEL  $PART5MOUNT  $PART5FSTYPE  $PART5FSOPTS 0 2" >> /tmp/fstab
                            if  [ "$P6SIZE" -gt 0  ]; then
                                format $PART6FSTYPE $PART6LABEL ${hd0dev}$P6PART
                                echo "LABEL=$PART6LABEL  $PART6MOUNT  $PART6FSTYPE  $PART6FSOPTS 0 2" >> /tmp/fstab
                                if  [ "$P7SIZE" -gt 0  ]; then
                                    format $PART7FSTYPE $PART7LABEL ${hd0dev}$P7PART
                                    echo "LABEL=$PART7LABEL  $PART7MOUNT  $PART7FSTYPE  $PART7FSOPTS 0 2" >> /tmp/fstab
                                fi
                            fi
                        fi
                    fi
                fi
            fi
        fi
    fi
  # let udev scan for new filesystem labels
    /sbin/udevadm trigger

    _log_msg "Done."
}

initialize_part_if_necessary () {
    hd0dev=$1
   # check for unpartitioned disk
   # and write a new label:
    fdisk -l $hd0dev 2>&1| grep "t contain a valid" > /dev/null && \
        fdisk $hd0dev <<EOT
o
w
EOT
    fdisk -l $hd0dev 2>&1| grep "No partitions found" > /dev/null && \
        fdisk $hd0dev <<EOT
o
w
EOT
}

get_part_sizes () {
  # to be called via eval, echoes SECTORSIZE, SECTORNUMBER, USEDPARTS
    local hd0dev=$1
  # get sector size (bytes)
    local SECTORSIZE=$(sfdisk -l $hd0dev -uS 2>/dev/null| gawk '/Units = sectors/{print $5}')
  # get number of sectors
    if [ -z "$SECTORSIZE" ]; then
        panic "# could not get SECTORSIZE"
    fi
    local SECTORNUMBER=$(sfdisk -l $hd0dev -uS 2>/dev/null| gawk '/sectors\/track/{print $3*$5*$7}')
    if [ -z "$SECTORNUMBER:" ]; then
        panic "# could not get SECTORNUMBER:"
    fi

  # get used primary partitions
    local NOTEMPTY=$(sfdisk -l $hd0dev -uS 2>/dev/null| grep ^/dev/ | gawk '!/Empty/{print $1}')
  # find partitions in use
    local USEDPARTS=""
    for i in $NOTEMPTY; do
        USEDPARTS="$USEDPARTS $i"
    done
    echo "SECTORSIZE=$SECTORSIZE"
    echo "SECTORNUMBER=$SECTORNUMBER"
    echo "USEDPARTS=\"$USEDPARTS\""
}

check_or_create_ext_part () {
    hd0dev=$1
    EXTPART=0
  # check for extended partition
    EXTPART_LASTSECTOR=$(sfdisk -l $hd0dev -uS 2>/dev/null| grep ^/dev/ | gawk '/Extended/{print $4}')
    if [ -z "$EXTPART_LASTSECTOR" ]; then
        for i in ${hd0dev}1 ${hd0dev}2 ${hd0dev}3 ${hd0dev}4;do
            case $USEDPARTS in
                *$i*)
        #skip
;;
*)
if [ "$EXTPART" = "0" ]; then
           # create an extended partition:
    EXTPART=${i#${hd0dev}}
    _log_msg "# will use partition $i for extended partition"
    if [ -n "$INTERACTIVE" ]; then
        echo "USEDPARTS:  ${USEDPARTS}"
        echo "NOTEMPTY:   ${NOTEMPTY}"
        echo "EXTPART:    ${EXTPART}"
        echo "SECTORSIZE: ${SECTORSIZE}"
        panic "about to create partition $i of $hd0dev as extended partition"
    fi
    fdisk $hd0dev <<EOT
n
e
$EXTPART


w
EOT
fi
;;
esac
done
else
     # get id of existing ext part
EXTPART=$(sfdisk -l $hd0dev -uS 2>/dev/null| gawk '/Extended/ {match($1,/^\/dev\/.*[a-z]([0-9]+)$/,a);print a[1];}')
fi
  # exit on error:
if [ "$EXTPART" = "0" ];then
    panic "could not create an extended partition! reset now or risc damage!"
fi
}

get_ext_part_sectors () {
    hd0dev=$1
  # now get first + last sector of ext part:
    eval $(sfdisk -l $hd0dev -uS 2>/dev/null| grep ^/dev/ | \
        gawk '/Extended/ {print "EXTPART_LASTSECTOR="$3,"EXTPART_FIRSTSECTOR="$2;}')
    if [ -z "$EXTPART_LASTSECTOR" ]; then
        dropshell "could not get EXTPART_LASTSECTOR"
    fi
  # get last used sector in ext part:
    eval $(sfdisk -l $hd0dev -uS 2>/dev/null|                                         \
        gawk 'BEGIN {lastsector=0;lastpart=0}                      \
        /^\/dev\// { match($1,/^\/dev\/.*[a-z]([0-9]+)$/,a); \
        partnr=a[1];                            \
        if(partnr>4)                            \
        if(lastsector<$3)                      \
        {lastsector=$3; lastpart=partnr}     \
        }                                        \
        END {print "LASTSECTOR="lastsector";LASTPART="lastpart}')
    if [ "$LASTSECTOR" = "0" ]; then
        LASTSECTOR=$(${EXPR} $EXTPART_FIRSTSECTOR + 63 )
    fi
    if [ "$LASTPART" = "0" ]; then
        LASTPART=4
    fi
    echo "LASTSECTOR=$LASTSECTOR LASTPART=$LASTPART EXTPART_LASTSECTOR=$EXTPART_LASTSECTOR EXTPART_FIRSTSECTOR=$EXTPART_FIRSTSECTOR"
}

parse_partitions() {
# to be called via eval, echoes variables EXT2, WIN and SWAP
# put TARGET partition as no 1:
    TARGETDEV=$(${MOUNT} | grep "$TARGET" | \
        gawk '/ext3/ {print $1}'| sort | uniq)
    if [ -n "$TARGETDEV" ]; then
        EXT2="$TARGETDEV"
    else
        EXT2=""
    fi
    SWAP=""
    WIN=""
    # determine bios drive 0x80:
    hd0dev=$(find_hd0)
    if [ -n "$hd0dev" ]; then
        fdisk=$(fdisk -l $hd0dev)
        PARTS_NTFS=$(find_ntfs $hd0dev)
        PARTS_FAT=$(find_fat $hd0dev)
        if  [ -z "${WIN}"  ]; then
            if  [ -z "$PARTS_NTFS"  ]; then 
                WIN="$PARTS_FAT"
            else
                WIN="$PARTS_NTFS $PARTS_FAT"
            fi
        else
            WIN="${WIN} $PARTS_NTFS $PARTS_FAT"
        fi
      # create an array Variable
        if [ -n "$TARGETDEV" ]; then 
        # skip TARGETDEV:
            PARTS=$(find_ext2 $hd0dev | sed -e "s#$TARGETDEV##g")
        else
            PARTS=$(find_ext2 $hd0dev)
        fi
        if  [ -z "${EXT2}"  ]; then
            EXT2="$PARTS"
        else
            EXT2="${EXT2} $PARTS"
        fi
      # create an array Variable
      # swap is now called Linux swap / Solaris !!
        PARTS=$(find_swap_dev $hd0dev)
        if  [ -z "${SWAP}"  ]; then
            SWAP="$PARTS"
        else
            SWAP="${SWAP} $PARTS"
        fi
    fi
    echo "EXT2=\"$EXT2\""
    echo "WIN=\"$WIN\""
    echo "SWAP=\"$SWAP\""
}


#
# /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 
#
# (modify-all-frames-parameters '((font . "Courier-14"))) 
#
