#!/system/bin/sh

# THIS FILE IS MODIFIED FROM THE ORIGINAL SUPERSU v2.74-2 DISTRIBUTION
#
# - MODE (and thus sukernel.daemonsu.launch) is intialized to init-sec-boot
# - rootfs is remounted r/w
# --- /su created
# --- /sbin set to 0755
# --- supolicy, sukernel, app_process symlinked to /su/bin/* from /sbin/.
# - "supolicy --live" is called before launching the daemon
# - daemon always started in from-service mode
#
# NOTE: use system modifying xposed, not systemless!
#
# Changes are marked with #S7QC

MODE=$1

#S7QC
if [ -z "$MODE" ]; then
  MODE=init-sec-boot
fi

log_print() {
  echo "($MODE) $1"
  log -p i -t launch_daemonsu "($MODE) $1"
}

if [ `mount | grep " /data " >/dev/null 2>&1; echo $?` -ne 0 ]; then
  # /data not mounted yet, we will be called again later
  exit
fi

if [ `mount | grep " /data " | grep "tmpfs" >/dev/null 2>&1; echo $?` -eq 0 ]; then
  # /data not mounted yet, we will be called again later
  exit
fi

if [ `cat /proc/mounts | grep /su >/dev/null 2>&1; echo $?` -eq 0 ]; then
  if [ -d "/su/bin" ]; then
    if [ `ps | grep -v "launch_daemonsu.sh" | grep "daemonsu" >/dev/null 2>&1; echo $?` -eq 0 ]; then
      # nothing to do here
      exit
    fi
  fi
fi

#S7QC
setprop sukernel.daemonsu.launch $MODE

loopsetup() {
  LOOPDEVICE=
  for DEV in $(ls /dev/block/loop*); do
    if [ `losetup $DEV $1 >/dev/null 2>&1; echo $?` -eq 0 ]; then
      LOOPDEVICE=$DEV
      break
    fi
  done
}

resize() {
  if [ `ls  -l /data/su.img | grep " 33554432 " >/dev/null 2>&1; echo $?` -eq 0 ]; then
    e2fsck -p -f /data/su.img
    resize2fs /data/su.img 96M
  fi
}

if [ ! -d "/su/bin" ]; then
  #S7QC
  mount -o rw,remount rootfs /
  mkdir /su
  chmod 0755 /sbin
  ln -s /su/bin/app_process /sbin/app_process
  ln -s /su/bin/supolicy /sbin/supolicy
  ln -s /su/bin/sukernel /sbin/sukernel

  # not mounted yet, do our thing
  REBOOT=false

  # copy boot image backups
  cp -f /cache/stock_boot_* /data/. 2>/dev/null

  if [ -f "/data/su.img" ]; then
    e2fsck -p -f /data/su.img

    # make sure the image is the right size
    resize
  fi

  # newer image in /cache ?
  # only used if recovery couldn't mount /data
  if [ -f "/cache/su.img" ]; then
    log_print "/cache/su.img found"
    e2fsck -p -f /cache/su.img
    OVERWRITE=true

    if [ -f "/data/su.img" ]; then
      # attempt merge, this will fail pre-M
      # will probably also fail with /system installed busybox,
      # but then again, is there anything busybox doesn't break?
      # falls back to overwrite

      log_print "/data/su.img found"
      log_print "attempting merge"

      mkdir /cache/data_img
      mkdir /cache/cache_img

      # setup loop devices

      loopsetup /data/su.img
      LOOPDATA=$LOOPDEVICE
      log_print "$LOOPDATA /data/su.img"

      loopsetup /cache/su.img
      LOOPCACHE=$LOOPDEVICE
      log_print "$LOOPCACHE /cache/su.img"

      if [ ! -z "$LOOPDATA" ]; then
        if [ ! -z "$LOOPCACHE" ]; then
          # if loop devices have been setup, mount images
          OK=true

          if [ `mount -t ext4 -o rw,noatime $LOOPDATA /cache/data_img >/dev/null 2>&1; echo $?` -ne 0 ]; then
            OK=false
          fi

          if [ `mount -t ext4 -o rw,noatime $LOOPCACHE /cache/cache_img >/dev/null 2>&1; echo $?` -ne 0 ]; then
            OK=false
          fi

          if ($OK); then
            # if mounts have succeeded, merge the images
            if [ `cp -af /cache/cache_img/. /cache/data_img >/dev/null 2>&1; echo $?` -eq 0 ]; then
              log_print "merge complete"
              OVERWRITE=false
            fi
          fi

          umount /cache/data_img
          umount /cache/cache_img
        fi
      fi

      losetup -d $LOOPDATA
      losetup -d $LOOPCACHE

      rmdir /cache/data_img
      rmdir /cache/cache_img
    fi

    if ($OVERWRITE); then
      # no /data/su.img or merge failed, replace
      log_print "replacing /data/su.img with /cache/su.img"
      mv /cache/su.img /data/su.img

      # make sure the new image is the right size
      resize
    fi

    rm /cache/su.img
  fi

  # do we have an APK to install ?
  if [ -f "/cache/SuperSU.apk" ]; then
    cp /cache/SuperSU.apk /data/SuperSU.apk
    rm /cache/SuperSU.apk
  fi
  if [ -f "/data/SuperSU.apk" ]; then
    log_print "installing SuperSU APK in /data"

    APKPATH=eu.chainfire.supersu-1
    for i in `ls /data/app | grep eu.chainfire.supersu- | grep -v eu.chainfire.supersu.pro`; do
      if [ `cat /data/system/packages.xml | grep $i >/dev/null 2>&1; echo $?` -eq 0 ]; then
        APKPATH=$i
        break;
      fi
    done
    rm -rf /data/app/eu.chainfire.supersu-*

    log_print "target path: /data/app/$APKPATH"

    mkdir /data/app/$APKPATH
    chown 1000.1000 /data/app/$APKPATH
    chmod 0755 /data/app/$APKPATH
    chcon u:object_r:apk_data_file:s0 /data/app/$APKPATH

    cp /data/SuperSU.apk /data/app/$APKPATH/base.apk
    chown 1000.1000 /data/app/$APKPATH/base.apk
    chmod 0644 /data/app/$APKPATH/base.apk
    chcon u:object_r:apk_data_file:s0 /data/app/$APKPATH/base.apk

    rm /data/SuperSU.apk

    sync

    # just in case
    REBOOT=true
  fi

  # sometimes we need to reboot, make it so
  if ($REBOOT); then
    log_print "rebooting"
    if [ "$MODE" = "post-fs-data" ]; then
      # avoid device freeze (reason unknown)
      sh -c "sleep 5; reboot" &
    else
      reboot
    fi
    exit
  fi

  # losetup is unreliable pre-M
  if [ `cat /proc/mounts | grep /su >/dev/null 2>&1; echo $?` -ne 0 ]; then
    loopsetup /data/su.img
    if [ ! -z "$LOOPDEVICE" ]; then
      mount -t ext4 -o rw,noatime $LOOPDEVICE /su
    fi
  fi

  # trigger mount, should also work pre-M, but on post-fs-data trigger may
  # be processed only after this script runs, causing a fallback to service launch
  if [ `cat /proc/mounts | grep /su >/dev/null 2>&1; echo $?` -ne 0 ]; then
    chcon u:object_r:system_data_file:s0 /data/su.img
    chmod 0600 /data/su.img
    setprop sukernel.mount 1
    sleep 1
  fi

  # exit if all mount attempts have failed, script is likely to be called again
  if [ `cat /proc/mounts | grep /su >/dev/null 2>&1; echo $?` -ne 0 ]; then
    exit
  fi

  # if other su binaries exist, route them to ours
  mount -o bind /su/bin/su /sbin/su 2>/dev/null
  mount -o bind /su/bin/su /system/bin/su 2>/dev/null
  mount -o bind /su/bin/su /system/xbin/su 2>/dev/null

  # poor man's overlay on /system/xbin
  if [ -d "/su/xbin_bind" ]; then
    cp -f -a /system/xbin/. /su/xbin_bind
    rm -rf /su/xbin_bind/su
    ln -s /su/bin/su /su/xbin_bind/su
    mount -o bind /su/xbin_bind /system/xbin
  fi
fi

# start daemon

#S7QC
/su/bin/supolicy --live
exec /su/bin/daemonsu --auto-daemon
