#!/bin/bash
#   description: mount and umount the filesystem

chkresult() {
  if [ $? -eq "0" ] ; then
    echo -e $RESULT_OK
  else
    echo -e $RESULT_FAIL
  fi
}

# flips a file upside down
flip() {
  local STRING
  while read -r STRING ; do
    flip
    echo "$STRING"        # New line needed
    break
  done

}

start() {
  mount   -n -o  remount,ro / >& /dev/null

  # I hate this, but it's required to make swapoff work if devfs is runing in /dev
  # it's clean and also simplifies the devfsd module
  # This scews up mtab
  grep -v '#' /etc/fstab | grep -v ^$ | grep -v noauto | \
  while read DEVICE MOUNTPOINT FSTYPE REST ; do 
    if [ "$DEVICE" = "devfs" ] ; then
      echo         -n "Mounting $MOUNTPOINT:"     
      mount        -n $MOUNTPOINT  &> /dev/null
      if [ $? -eq "0" ] ; then
        if [ -x /sbin/devfsd ] ; then
          echo     -e $RESULT_OK
          echo     -n "Starting devfsd on $MOUNTPOINT:"
          devfsd   $MOUNTPOINT  &> /dev/null
          chkresult
        fi
      else
        echo -e $RESULT_FAIL
      fi
    fi
  done

  swapon  -a &> /dev/null     &&
  chkresult

  if  [ ! -e /fastboot ] ; then 
    if [ -e /forcefsck ] ; then
      FORCE="-f"
    fi
    echo      "Checking file systems: "
    fsck      -A -y -a
    if [ $? -eq "0" ] ; then
      echo    -e $RESULT_OK
    else
      if [ $? -eq "1" ] ; then    # Don't force the poor guy into resuce mode, if fscked cleaned it
        echo  -e $RESULT_WARN
      else
        echo  -e "fsck failed.$RESULT_FAIL"
        echo  "Please repair your file system"
        echo  "manually by running /sbin/fsck"
        echo  "without the -a option"
        sulogin
        reboot  -f
      fi
    fi
  fi

  echo       -n "Remounting root readwrite"
  mount      -n -o remount,rw /  &> /dev/null
  echo       > /etc/mtab
  rm         -f /etc/mtab~*      &> /dev/null
  mount      -f -o remount,rw /  &> /dev/null
  chkresult  

  # /etc/fast should be in order
  # ex. /usr should comes before /usr/local
  # and /proc before /proc/bus/usb
  # better to fail if a mounting dosn't exist than, do it silently
  grep -v '#' /etc/fstab | grep -v ^$ | grep -v noauto | 
  while  read  DEVICE MOUNTPOINT FSTYPE REST;  do
  
    # Filter out already mounted fs's: devfs and root
    # We should have mounted all devfs before, now a hack to get it into /etc/mtab
    if [ "$DEVICE" == "devfs" ] ; then
      mount -f -t devfs devfs $MOUNTPOINT
      continue
    fi 
    if [ "$MOUNTPOINT" == "/" ] ; then
      continue
    fi

    # we don't do networked fs's yet!
    case "$FSTYPE" in
      nfs|smbfs) continue ;;
    esac

    # End filter

    if [ "$MOUNTPOINT" != "none" ] ; then
      echo    -n "Mounting: $MOUNTPOINT"
      mount   $MOUNTPOINT         &> /dev/null
      if [ $? -ne "0" ] ; then
        if [ "$DEVICE" == "usbdevfs" ] || [ "$DEVICE" == "usbfs" ] ; then          # Load the module for usbdevfs if need
          modprobe usbcore        &> /dev/null
          mount    $MOUNTPOINT    &> /dev/null
          chkresult
        else
          echo -e $RESULT_FAIL
        fi
      else
        echo  -e $RESULT_OK
      fi
    fi

  done

  rm         -f /fastboot /forcefsck
}


stop() {

  # Establish where to get mount table from, save these since the files change if we unmount something
  if [ -r /proc/mounts ] ; then
    MOUNTS=/proc/mounts
  else
    MOUNTS=/etc/mtab
  fi
	
  # Umount all tmpfs fist
  # cat it with a pipe cause it  will change if we umount anything, thus become shakeing

  # write wtmp in /var before umounting /var
  reboot -w
  
  echo "Umounting all filesystems:"
	
  cat $MOUNTS | flip | \
  while read TYPE PNT FS REST ; do
    
    SIG=-3

    if [ "$FS" == "nfs" ] || [ "$FS" == "smbfs" ] ; then              # Don't umount smbfs and nfs because they should of been handled by another script
      continue                                                        # and if they are here that means they are frozen, don't want anymore freezing
    fi
    if [ "$PNT" == "/" ] || [ "$PNT" == "/proc" ] ; then              # Leave these two for last
      continue
    fi

    echo  -n " Umounting: $PNT"
		
    for TRY in "1" "2" "3" ; do			
      if [ $TRY -eq "1" ] ; then
         umount    $PNT  &> /dev/null
      else
        if [ $TRY -eq "3" ] ; then
          SIG=-9
        fi
        fuser      -s -km $SIG $PNT &> /dev/null  
        umount     -f $PNT &> /dev/null
      fi

      # Make sure the buffer are flushed, this goes after umount to make sure, it's umounted _NOW_
      sync ; sync

      TEST=$(cat $MOUNTS | grep "$PNT" | awk '{ print $1}')

      if [ "$TEST" == "$TYPE" ] && [ $TRY -eq "3" ] ; then
        echo       -e $RESULT_FAIL
        echo       -n " Attempting to remount read only: $PNT"
        mount      -o remount,ro $PNT &> /dev/null
        chkresult
      else
        if [ "$TEST" == "$TYPE" ] ; then
          continue
        fi
      fi

      echo         -e $RESULT_OK
      if [[ "$TYPE" == "/dev/loop"* ]] ; then
        if [ -e $PNT ] ; then                                       # Devfs and some loopback devices (iso images)
          echo:    -n " Deataching loopback device $PNT:"            # can take care of them selfs
          losetup  -d $PNT &> /dev/null
          chkresult
        fi
      fi
      continue 2
    done
  done
  
  echo -n " Deactivating swap space:"
  swapoff  -a
  chkresult
  
  sync; sync

  # Don't umpunt /proc because it can and will crash when umounting any remaining filesystems
  # on some systems

  echo    -n " Remounting root readonly"
  mount   -no remount,ro /
  chkresult
  
  if [ $? -ne "0" ] ; then
    read  -n 1  -t 30  -p  "Do you want to login? (y/n) "  CONFIRM
    echo
    case  $CONFIRM in
      y|Y)  sulogin ;;
    esac
  fi

  # Last chance to flush before reboot
  sync; sync

  # Should probly use hdparm at this point to put the hds to sleep
  # Give the hd a chance to slow down
  sleep 3
}

# to avoid confusion we force only these options as being valid:
case "$1" in
  start|stop) ;;
           *) echo  "Usage: $0 {start|stop}"  ;;
esac

. /lib/lsb/init-functions

