#!/bin/sh
#Mount filesystem to AUFS
#VERSION 4.4

if [ -f $(dirname $0)/pfs ] ;  then
    . $(dirname $0)/pfs
else 
    . $(which pfs) || exit 13 
fi    

mntmode="upper"

HLP() {
  echo "Usage: $(basename "$0") [OPTIONS] [MODULES and DIRS LIST] "
  echo "Options:"
  echo " -u,   --upper    (default) Mount filesystem to upper layer (AUFS)."
  echo " -l,   --lower    Mount filesystem to lower layer (AUFS)."
  echo " -n,   --no-update Do not check for update caches"
  echo " --ro, --read-only Mount read-only"
  echo " -r,   --toram copy module to RAM disk (tmpfs) before loading"
}

toram () {
mkdir -p ${copyramdir}
df   ${copyramdir} |grep -Eq '^tmpfs|^/dev/zram'  || mountb -t tmpfs tmpfs "${copyramdir}"
freeram=$(checkramfreeb)
filesize="$(du -k "${fsfile}" | cut -f 1)"
minram="$(( ${filesize} + ${TMPFSLIMIT} ))"
[ "${minram}" -gt "${freeram}" ] && exitmsg "Not enough free RAM space" 3
if [ -f "${copyramdir}/${fsname}" ] ;then 
	pfsunload -r ${fsname} 
	exitmsg "File already in ram and mounted" $?
fi
#echo "\"${fsname}\" copy to RAM..."
cp -afL "${fsfile}" "${copyramdir}" || return 2
echo  "${copyramdir}/$(basename ${fsfile})" | sed 's://:/:g'
}

#get opts
sourcelist=""
for arg in "$@"
do
  case "${arg}" in
    "-u"   | "--upper") mntmode="upper";;
    "-l"   | "--lower") mntmode="lower";;
    "-n"   | "--no-update") fupdate="no";;
    "-r"   | "--toram" ) toram="yes" ;;
    "--ro" | "--read-only" ) romode="yes";;
    "-h"   | "--help") HLP; break;;
    "-"*[A-Za-z]*) exitmsg "$(basename "$0"): invalid option -- '$(echo ${arg} | tr -d '-')'" 1 ;;
    *) sourcelist="${sourcelist},${arg}";;
   esac
done

[ "$sourcelist" ] || HLP 

allow_only_root
 
echo $sourcelist |sed 's/,/\n/' |while read infile  ; do
[ -z "$infile" ] && continue
if [ -f "${infile}" ]; then
  fsfile="$(realpath "${infile}")"
  [ $toram ] && fsfile=$(toram)
  devtype="file"
elif [ -b "${infile}" ]; then
  fsfile="${infile}"
  devtype="dev"
elif [ -d "${infile}" ]; then
  fsfile="$(realpath "${infile}")"
  devtype="dir"
else
  exitmsg "Object \"${infile}\" not found!"  2
fi

if [ "${devtype}" != "dir" ]; then
  fstype=$(fs_type "${fsfile}")
  [ "${fstype}" = "" ] && exitmsg "Unknown file system -- \"$fsfile\"" 3
  [ checksfsxzb 2>/dev/null ] || exitmsg "Kernel not support PFS!" 4
else
  fsinfo="$(df -aT "${fsfile}" | tail -n 1 | tr -s ' ' '_' | cut -d'_' -f 2)"
  case "${fsinfo}" in
    "ntfs"|"fat32"|"aufs") exitmsg "\"$fsinfo\" -- isn't supported FS" 5;;
  esac
  fstype="${fsinfo}"
fi
  
fsname="$(basename "${fsfile}")"
mountpoint="${prefixmp}${fsname}"
[ -d "${mountpoint}" ] && rmdir "${mountpoint}" 2>/dev/null
[ -d "${mountpoint}" ] && exitmsg "Object \"${fsfile}\" is mounted!" 6

if [ "${devtype}:${fstype}" = "file:squashfs" ]; then
  sync
  freeloop=0
  looplist="$(losetupb -a)"
  while true ; do
    echo "${looplist}" | grep -q -F "/dev/loop${freeloop}" && freeloop="$(expr ${freeloop} + 1)" || break
  done
  if [ ! -b /dev/loop${freeloop} ]; then
    mknod -m660 /dev/loop${freeloop} b 7 ${freeloop}
    chown root.root /dev/loop${freeloop}
    sync
  fi
  [ -b /dev/loop${freeloop} ] || exitmsg "Error! Free loop devices is not found!" 7
  losetupb /dev/loop${freeloop} "${fsfile}"
  status=$?
else
  status=0
fi

if [ ${status} -eq 0 ]; then
  mkdir -p "${mountpoint}"
  
  sync
  case "${devtype}" in
    "file" )  if [ "${fstype}" = "squashfs" ]; then
                mountb -t squashfs -o ro /dev/loop${freeloop} "${mountpoint}" >/dev/null #2>&1
              else
                [ "${romode}" ] && optmnt="loop,ro" || optmnt="loop"
                mountb -t ${fstype} -o ${optmnt} "${fsfile}" "${mountpoint}" >/dev/null #2>&1
              fi;;
    "dev" )   [ "${romode}" ] && optmnt="ro" || optmnt="rw"
              mountb -t ${fstype} -o ${optmnt} "${fsfile}" "${mountpoint}" >/dev/null ;;
    #"dir" )   mountb -t ${fstype} --bind "${fsfile}" "${mountpoint}" >/dev/null ;;
    "dir" )   mountb --bind "${fsfile}" "${mountpoint}" >/dev/null ;;
  esac 
  status=$?
  
  if [ ${status} -eq 0 ]; then
    sync
    [ "$devtype" = "file" ] && requires="$requires $(checkdeps "${mountpoint}" 2>/dev/null)"
    if [ "${mntmode}" = "upper" ]; then
		nlayer=1
		[ -w $(aufs-n 1) ] && nlayer=2
		[ -w "${mountpoint}" ] && nlayer=1
		mountb -o remount,add:${nlayer}:"${mountpoint}"=ro+wh / >/dev/null #2>&1
    else
      mountb -o remount,append:"${mountpoint}"=ro+wh / >/dev/null #2>&1
    fi
    status=$?
    sync
    
    if [ ${status} -eq 0 ]; then
        [ "${fupdate}" != "no" ] && pfs_update_caches "${mountpoint}" 
    else
      umountb -d "${mountpoint}" >/dev/null
	  rmdir "${mountpoint}" >/dev/null
	  exitmsg "AUFS error!" ${status}
    fi
    
  else
    losetupb -d /dev/loop${freeloop}
    rmdir "${mountpoint}" >/dev/null
	exitmsg "Unable to mount \"${fsfile}\" in \"${mountpoint}\"." ${status}
  fi
  
else
  rmdir "${mountpoint}" 2>/dev/null
  exitmsg "Mount error!" ${status}
fi

sync
for script in $(find $(dirname $0) -maxdepth 1 -name "runpfsload*" -user root) ; do 
	$script "${mountpoint}" &
done

for dep in $requires ; do
	echo "need: $dep"
done

done
exit 0
