#!/bin/bash
# This is 'probe', a wrapper for using fdisk to gather drive info for
# the Dragora setup scripts.  Probe is based on the 'probe' of
# Slackware Linux -- included on the initrd.img.

TMP=${TMP:-/var/tmp/installer}
[[ ! -d ${TMP} ]] && mkdir -p "$TMP"
rm -f ${TMP}/SeTfdisk

# listide major minor hd1 hd2 (2 base devs for major)
list_ide() {
  if [[ $2 -eq 0 ]]; then
    fdisk -l /dev/$3 >> ${TMP}/SeTfdisk
  elif [[ $2 -eq 64 ]]; then
    fdisk -l /dev/$4 >> ${TMP}/SeTfdisk
  fi
}

list_scsi() {
  # find drive # 0 - 15
  local DRV
  DRV=$1
  DRV=$((DRV / 16))
  NUM=$((DRV % 16))
  if [[ $NUM -ne 0 ]]; then
    return;
  fi
  case "$DRV" in
    0)  fdisk -l /dev/sda >> ${TMP}/SeTfdisk;;
    1)  fdisk -l /dev/sdb >> ${TMP}/SeTfdisk;;
    2)  fdisk -l /dev/sdc >> ${TMP}/SeTfdisk;;
    3)  fdisk -l /dev/sdd >> ${TMP}/SeTfdisk;;
    4)  fdisk -l /dev/sde >> ${TMP}/SeTfdisk;;
    5)  fdisk -l /dev/sdf >> ${TMP}/SeTfdisk;;
    6)  fdisk -l /dev/sdg >> ${TMP}/SeTfdisk;;
    7)  fdisk -l /dev/sdh >> ${TMP}/SeTfdisk;;
    8)  fdisk -l /dev/sdi >> ${TMP}/SeTfdisk;;
    9)  fdisk -l /dev/sdj >> ${TMP}/SeTfdisk;;
    10) fdisk -l /dev/sdk >> ${TMP}/SeTfdisk;;
    11) fdisk -l /dev/sdl >> ${TMP}/SeTfdisk;;
    12) fdisk -l /dev/sdm >> ${TMP}/SeTfdisk;;
    13) fdisk -l /dev/sdn >> ${TMP}/SeTfdisk;;
    14) fdisk -l /dev/sdo >> ${TMP}/SeTfdisk;;
    15) fdisk -l /dev/sdp >> ${TMP}/SeTfdisk;;
  esac
}

# List Mylex RAID device
list_rd() {
  # find drive
  local DRV
  DRV=$2
  DRV=$((DRV / 8))
  NUM=$((DRV % 8))
  if [[ $NUM -ne 0 ]]; then
    return;
  fi
  fdisk -l /dev/rd/c$1d${DRV} >> ${TMP}/SeTfdisk
}

# List Cpq SMART/2 RAID device
list_ida() {
  # find drive
  local DRV
  DRV=$2
  DRV=$((DRV / 16))
  NUM=$((DRV % 16))
  if [[ $NUM -ne 0 ]]; then
    return;
  fi
  fdisk -l /dev/ida/c$1d${DRV} >> ${TMP}/SeTfdisk
}

list_cciss() {
  # find drive
  local DRV
  DRV=$2
  DRV=$((DRV / 16))
  NUM=$((DRV % 16))
  if [[ $NUM -ne 0 ]]; then
    return;
  fi
  fdisk -l /dev/cciss/c$1d${DRV} >> ${TMP}/SeTfdisk
}

list_ataraid() {
  # find drive
  local DRV
  DRV=$2
  DRV=$((DRV / 16))
  NUM=$((DRV % 16))
  if [[ $NUM -eq 0 ]]; then
     fdisk -l /dev/ataraid/d${DRV} >> ${TMP}/SeTfdisk
  else
     return;
  fi
}

list_amiraid() {
  # find drive
  local DRV
  DRV=$2
  DRV=$((DRV / 16))
  NUM=$((DRV % 16))
  if [[ $NUM -eq 0 ]]; then
     fdisk -l /dev/amiraid/ar${DRV} >> ${TMP}/SeTfdisk
  else
     return;
  fi
}

is_swap() {
  HEADER=$(dd if="$1" bs=1 skip=4086 count=10 2>/dev/null)
  if [[ $HEADER = SWAPSPACE2 || $HEADER = SWAP_SPACE ]]; then
    return 0;
  else
    return 1;
  fi
}

list_md() {
  if ( is_swap "/dev/$2" ); then TYPE="Linux swap"; else TYPE="Linux"; fi
  echo "/dev/$2  1 2 $1 kk $TYPE" >> ${TMP}/SeTfdisk
}

list_lvm() {
  lvscan 2>/dev/null | grep -i ACTIVE | while read line ; do
    [[ ${#line} -eq 0 ]] && break;
    DEV=$(echo $line | cut -f2 -d \')
    SIZE=$(lvdisplay $DEV -C --units k | awk '{ size = $4 }; END { print size }' | cut -f1 -d .)
    TYPE="Linux"
    if ( is_swap "$DEV" ); then TYPE="Linux swap"; fi
    echo "$DEV  0  0  $SIZE  lv  $TYPE" >> ${TMP}/SeTfdisk
  done
}

# List any volumes created by cryptsetup
list_crypt() {
  for i in /dev/mapper/* ; do
    if cryptsetup status $i 2>/dev/null | grep -q "is active" ; then
      DEV=$(cryptsetup status $i 2>/dev/null | grep "is active" | cut -f1 -d' ')
      SIZE=$(fdisk -s $(cryptsetup status $i 2>/dev/null | grep "device:" | cut -f2 -d: | tr -d ' '))
      echo "$DEV  0  0  $SIZE  lc  Linux" >> ${TMP}/SeTfdisk
    fi
  done
}

# List the LVM volumes:
list_lvm

# Lyst CRYPT volumes:
list_crypt

# Other partitions:
if grep -q / /proc/partitions ; then # new
  grep / /proc/partitions | while read line ; do
    SMASHED_LINE=$line
    MAJOR=$(echo $SMASHED_LINE | cut -f 1 -d ' ')
    MINOR=$(echo $SMASHED_LINE | cut -f 2 -d ' ')
    case "$MAJOR" in
      3)   list_ide $MAJOR $MINOR hda hdb;;
      8)   list_scsi $MINOR;;
      9)   list_md $(echo $SMASHED_LINE | cut -f 3 -d ' ' | tr -d '/') \
                   $(echo $SMASHED_LINE | cut -f 4 -d ' ');;
      22)  list_ide $MAJOR $MINOR hdc hdd;;
      33)  list_ide $MAJOR $MINOR hde hdf;;
      34)  list_ide $MAJOR $MINOR hdg hdh;;
      48)  list_rd 0 $MINOR;;
      49)  list_rd 1 $MINOR;;
      50)  list_rd 2 $MINOR;;
      51)  list_rd 3 $MINOR;;
      52)  list_rd 4 $MINOR;;
      53)  list_rd 5 $MINOR;;
      54)  list_rd 6 $MINOR;;
      55)  list_rd 7 $MINOR;;
      56)  list_ide $MAJOR $MINOR hdi hdj;;
      57)  list_ide $MAJOR $MINOR hdk hdl;;
      72)  list_ida 0 $MINOR;;
      73)  list_ida 1 $MINOR;;
      74)  list_ida 2 $MINOR;;
      75)  list_ida 3 $MINOR;;
      76)  list_ida 4 $MINOR;;
      77)  list_ida 5 $MINOR;;
      78)  list_ida 6 $MINOR;;
      79)  list_ida 7 $MINOR;;
      80)  list_ide $MAJOR $MINOR hdm hdn;;
      89)  list_ide $MAJOR $MINOR hdo hdp;;
      90)  list_ide $MAJOR $MINOR hdq hdr;;
      91)  list_ide $MAJOR $MINOR hds hdt;;
      101) list_amiraid $MAJOR $MINOR;;
      104|105|106|107|108|109|110|111)
           list_cciss $((MAJOR - 104)) $MINOR;;
      114) list_ataraid $MAJOR $MINOR;;
    esac
  done
else # old format and no RAID:
  if grep -q md /proc/partitions ; then
    grep md /proc/partitions | while read line ; do
      SMASHED_LINE=$line
      MAJOR=$(echo $SMASHED_LINE | cut -f 1 -d ' ')
      if [[ $MAJOR -eq 9 ]]; then
        list_md $(echo $SMASHED_LINE | cut -f 3 -d ' ' | tr -d '/') \
                $(echo $SMASHED_LINE | cut -f 4 -d ' ')
      fi
    done
  fi
  fdisk -l >> ${TMP}/SeTfdisk
fi

cat ${TMP}/SeTfdisk
