#!/bin/bash
# (C) Klaus Knopper Nov 2002
# Calls scanpartitions as root and adds entries to /etc/fstab

PATH="/bin:/sbin:/usr/bin:/usr/sbin"
export PATH
umask 022

# fstype

# Simple shell grep, searches for lines STARTING with string
stringinfile(){
while read line; do
case "$line" in $1*) return 0;; esac
done <"$2"
return 1
}

removeentries(){
# Remove comment line $1 and the following line from file $2
# sed '/^# Added by KNOPPIX/{N;d;}'
while read line; do
case "$line" in $1) read line; continue ;; esac
echo "$line"
done <"$2"
}

fstype()
{

if [ -n "$PARTITION" ]; then
# Check if partition is already mounted
 while read device mountpoint filesystem relax; do
  case "$device" in *$PARTITION*) SCANFS="$filesystem"; return 0;; esac
  done <<EOT
$(cat /proc/mounts)
EOT

# Check if a device/medium is present at all
 dd if="$PARTITION" count=1 bs=1k >/dev/null 2>&1 || return 1
 FILE="$(LANG=C LC_ALL=C LC_MESSAGES=C file -Lkbs "$PARTITION")"
 [ "$?" = "0" ] || exit 3
 if [ "$FILE" = "data" ]; then
 # could still be ReiserFS, since "file" only reads 64k in Debian
   FILE="$(dd if="$PARTITION" skip=16397 ibs=4 count=2 2>/dev/null)"
 fi
 case "$FILE" in
  *[Rr][Ee][Ii][Ss][Ee][Rr]*)  SCANFS="reiserfs";;
  *ISO\ 9660*)                 SCANFS="iso9660";;
  *[Mm][Ii][Nn][Ii][Xx]*)      SCANFS="minix";;
  *[Xx][Ff][Ss]*)              SCANFS="xfs";;
  *[Jj][Ff][Ss]*)              SCANFS="jfs";;
  *[Ee][Xx][Tt]3*)             SCANFS="ext3";;
  *[Ee][Xx][Tt]2*)             SCANFS="ext2";;
  *[Ss][Ww][Aa][Pp]*)          SCANFS="swap";;
  *[Nn][Tt][Ff][Ss]*)          SCANFS="ntfs";;
  *[Ff][Aa][Tt]*)              SCANFS="vfat";;
  *)                           SCANFS="auto";;
 esac
else
 echo "Usage: $0 partition|disk" >&2
 echo "   returns \"partition fstype\" lines to stdout." >&2
 return 1
fi

return 0
}

# scanpartitions
scanpartitions()
{

partitions=""
disks=""
disksize=0
blocksum=0
pold="none"
while read major minor blocks partition relax; do
partition="${partition#/dev/}"
[ -z "$partition" -o ! -e "/dev/$partition" ] && continue
[ "$blocks" -lt 2 ] 2>/dev/null && continue
case "$partition" in
?d?|ataraid/d?) disks="$disks $partition"; disksize="$blocks"; blocksum=0;;
ram*|cloop*|loop*) ;; # Kernel 2.6 bug?
*) blocksum="$(($blocksum + $blocks))"; [ "$blocksum" -gt "$disksize" ] >/dev/null 2>&1 || partitions="$partitions /dev/$partition";;
esac
done <<EOT
$(awk 'BEGIN{old="__start"}{if($0==old){exit}else{old=$0;if($4&&$4!="name"){print $0}}}' /proc/partitions)
EOT

# Add disks without partition table (probably ZIP drives)
for d in $disks; do
case "$partitions" in */dev/$d*) continue;; esac
partitions="$partitions /dev/$d"
done

for p in $partitions; do
fs="auto"
# fstype is an external script
PARTITION="$p"
fstype
[ -n "$SCANFS" ] && fs="$SCANFS"
mountpoint="/mnt/${p##*/}"
[ "$fs" = "swap" ] && mountpoint="swap"
echo "${p}" "${mountpoint}" "${fs}"
done

return 0
}

# rebuildfstab

[ ! -e /proc/partitions ] && { echo "$0: /proc not mounted, exiting" >&2; exit 1; }

if [ -e /var/run/rebuildfstab.pid ]; then
 ps "$(</var/run/rebuildfstab.pid)" >/dev/null 2>&1 && exit 0
 rm -f /var/run/rebuildfstab.pid
fi

echo "$$" >/var/run/rebuildfstab.pid

if [ "`id -u`" != "0" ] 
then
  echo $"root permission needed."
  exit 0
fi


TMP="/tmp/fstab.$$.tmp"
ADDEDBYBOOYO="# Added by BOOYO"

verbose=""
remove=""
user=""
group=""
arg="$1"
while [ -n "$arg" ]; do
 case "$arg" in
  -v*) verbose="yes" ;;
  -r*) remove="yes" ;;
  -u*) shift; user="$1" ;;
  -g*) shift; group="$1" ;;
  *) echo "Usage: $0 [-v[erbose]] [-r[emove_old]] [-u[ser] uid] [ -g[roup] gid]" ;;
 esac
 shift
 arg="$1"
done

[ -n "$verbose" ] && echo "Scanning for new harddisks/partitions..." >&2
rm -f "$TMP"

if [ -n "$remove" ]; then
 removeentries "$ADDEDBYBOOYO" /etc/fstab >"$TMP"
else
 cat /etc/fstab >"$TMP"
fi

scanpartitions | (count=0
while read device mountpoint fstype relax; do
 stringinfile "$device " "$TMP" || \
 { count="$((count + 1))"
   [ -d "$mountpoint" ] || mkdir -p "$mountpoint" 2>/dev/null
   options="noauto,users,exec"
   case "$fstype" in
    ntfs) options="${options},ro,umask=000" ;;
    vfat|msdos) options="${options},umask=000" ;;
    swap) options="defaults" ;;
   esac
   case "$fstype" in
   ntfs|vfat|msdos)
   [ -n "$user" ] && options="$options,uid=$user"
   [ -n "$group" ] && options="$options,gid=$group"
   ;;
   esac
   echo "$ADDEDBYBOOYO"
   echo "$device $mountpoint $fstype $options 0 0"; }
done >>"$TMP"
)

[ -n "$verbose" ] && { [ "$count" -gt 0 ] && echo "Adding $count new partitions to /etc/fstab." >&2 || echo "No new partitions found." >&2; }
mv -f "$TMP" /etc/fstab

rm -f /var/run/rebuildfstab.pid

exit 0
