shakalaca
9/26/2016 - 11:34 AM

Let's make panini .. XD

Let's make panini .. XD

#!/system/bin/sh
# Panini by shakalaca@23pin
########## environment variables ##########

MODE=$1

# block device and mount point for panini, configure before using
CONTAINER_DEV=/dev/block/bootdevice/by-name/APD
# special case for ZenFone x86
if [ -L /dev/block/by-name/APD ]; then
  CONTAINER_DEV=/dev/block/by-name/APD
fi
CONTAINER_MNT=/APD

LOG_FILE=/cache/panini.log
UNBLOCK_FILE=/cache/panini.post-fs

ROOT_MNT_SYSTEM=$CONTAINER_MNT/system_mnt
ROOT_BIND_SYSTEM=$CONTAINER_MNT/system_bind
ROOT_PANINI=$CONTAINER_MNT/panini

########## routines ##########

getvar() {
  local VARNAME=$1
  local VALUE=$(eval echo \$"$VARNAME");
  for FILE in /data/panini/config /cache/panini.conf; do
    if [ -z "$VALUE" ]; then
      LINE=$(cat $FILE 2>/dev/null | grep "$VARNAME=")
      if [ ! -z "$LINE" ]; then
        VALUE=${LINE#*=}
      fi
    fi
  done
  eval $VARNAME=\$VALUE
}

log_print() {
  echo "$1" >> $LOG_FILE
}

get_mount_dev() {
  _mount=`cat /proc/mounts | grep "$1"`
  echo ${_mount% /*}
}

get_selinux_context() {
  F_INFO=(`ls -Z $1`)
  echo ${F_INFO[3]}
}

bind_mount() {
  log_print "Mount $1 to $2"
  mount -o bind $1 $2
}

touch_perm() {
  log_print "Touching $1"
  touch $1
  chmod 644 $1
}

mkdir_perm() {
  log_print "Creating tree $1"
  mkdir -p $1
  chmod 755 $1
  if [ ! -z "$2" ]; then
    chcon $2 $1
  fi
}

is_mounted() {
  cat /proc/mounts | grep $1 >/dev/null
  return $?
}

is_os_upgraded() {
  OS_VERSION=`cat /system/build.prop|grep ro.build.fingerprint`
  PANINI_VERSION=`cat /data/panini/version 2>/dev/null`
  if [ "$OS_VERSION" != "$PANINI_VERSION" ]; then
    cat /system/build.prop|grep ro.build.fingerprint > /data/panini/version
    echo "true"
  else
    echo "false"
  fi
}

is_dir_changed() {
  LS_INFO=(`ls -l ${ROOT_PANINI%/*} | grep " ${ROOT_PANINI##*/}$"`)
  CURRENT_MODIFY="${LS_INFO[3]} ${LS_INFO[4]}"
  PANINI_MODIFY=`cat /data/panini/modify 2>/dev/null`
  if [ "$CURRENT_MODIFY" != "$PANINI_MODIFY" ]; then
    echo $CURRENT_MODIFY > /data/panini/modify
    echo "true"
  else
    echo "false"
  fi
}

process() {
  for f in `ls $2`; do
    local SOURCE=$2/$f
    local TARGET=$ROOT_BIND_SYSTEM${2#$1}/$f
    local PANINI=$ROOT_PANINI${2#$1}/$f

    # symbolic link
    if [ -L $SOURCE ]; then
      cp -an $SOURCE $TARGET
    # directory
    elif [ -d $SOURCE ]; then
      if [ -d $PANINI ] || [ "$f" == "bin" ] || [ "$f" == "xbin" ]; then
        # check if removed by request
        if [ ! -f $PANINI/.remove ]; then
          mkdir_perm $TARGET
          process $1 $SOURCE
        fi
      else
        mkdir_perm $TARGET
      fi
    # file
    else
      if [[ $2 == *bin ]] || [[ $2 == *xbin ]]; then
        cp -an $SOURCE $TARGET
        local F_SECONTEXT=$(get_selinux_context $SOURCE)
        if [ "$F_SECONTEXT" != "u:object_r:system_file:s0" ]; then
          chcon $F_SECONTEXT $TARGET
        fi
      else
        touch_perm $TARGET
      fi
    fi
  done
}

process_after_bind_tree() {
  EXEC_FILE=/data/panini/after_bind_tree.sh
  if [ -f $EXEC_FILE ]; then
    chmod +x $EXEC_FILE
    eval ". $EXEC_FILE"
  fi
}

exit_unblock() {
  touch_perm $UNBLOCK_FILE
  exit 0
}

########## main ##########

if [ ! -d /data/panini ]; then
  mkdir_perm /data/panini
fi

getvar CONTAINER_DEV
getvar CONTAINER_MNT
getvat ROOT_MNT_SYSTEM
getvar ROOT_BIND_SYSTEM
getvar ROOT_PANINI

if [ ! $(is_mounted $CONTAINER_MNT) ]; then
  mount -r -w -t ext4 -o noatime $CONTAINER_DEV $CONTAINER_MNT
fi

if [ ! $(is_mounted $ROOT_MNT_SYSTEM) ]; then
  mkdir_perm $ROOT_MNT_SYSTEM u:object_r:system_file:s0
  mount -r -t ext4 -o noatime $(get_mount_dev " /system ") $ROOT_MNT_SYSTEM
fi

if [ ! -d $ROOT_PANINI ]; then
  mkdir_perm $ROOT_PANINI u:object_r:system_file:s0
fi

if [ -f /data/panini/disabled ] || [ -f /cache/panini.disabled ]; then
  exit_unblock
fi

if [ "$MODE" == "stage1" ]; then
  mv $LOG_FILE ${LOG_FILE}_last

  OS_DIRTY=$(is_os_upgraded)
  TREE_DIRTY=$(is_dir_changed)
  if [ ! -f /data/panini/not-dirty ] && [ ! -f /cache/panini.not-dirty ] && ([ $OS_DIRTY == "true" ] || [ $TREE_DIRTY == "true" ]); then
    rm -rf $ROOT_BIND_SYSTEM
    mkdir_perm $ROOT_BIND_SYSTEM u:object_r:system_file:s0

    process $ROOT_PANINI $ROOT_PANINI
    process /system /system
    
    process_after_bind_tree
  fi
elif [ "$MODE" == "stage2" ]; then
  bind_mount $ROOT_BIND_SYSTEM /system
  export LD_LIBRARY_PATH=$ROOT_MNT_SYSTEM/lib:$ROOT_MNT_SYSTEM/vendor/lib
  if [ -d $ROOT_MNT_SYSTEM/lib64 ]; then
    export LD_LIBRARY_PATH=$ROOT_MNT_SYSTEM/lib64:$ROOT_MNT_SYSTEM/vendor/lib64
  fi

  for bind_f in `find $ROOT_BIND_SYSTEM -type f -o -type d`; do
    # do not bind 'bin' & 'xbin' since they were copied
    if [[ $bind_f == $ROOT_BIND_SYSTEM/bin* ]] || [ $bind_f == $ROOT_BIND_SYSTEM/xbin* ]; then
      continue
    fi

    TARGET=/system${bind_f#$ROOT_BIND_SYSTEM}
    PANINI=$ROOT_PANINI${bind_f#$ROOT_BIND_SYSTEM}
    ORIGIN=$ROOT_MNT_SYSTEM${bind_f#$ROOT_BIND_SYSTEM}

    if [ -d $PANINI ]; then
      log_print "Skip binding $TARGET"
    elif [ -f $PANINI ]; then
      bind_mount $PANINI $TARGET
    else
      bind_mount $ORIGIN $TARGET
    fi
  done
fi

exit_unblock

on post-fs
    export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin:/bin
    rm /cache/panini.post-fs

    # stage 1
    start make_panini
    wait /cache/panini.post-fs 50
    rm /cache/panini.post-fs

    # stage 2
    start enjoy_panini
    wait /cache/panini.post-fs 50
    rm /cache/panini.post-fs

service make_panini /sbin/panini.sh stage1
    user root
    seclabel u:r:init:s0
    oneshot

service enjoy_panini /sbin/panini.sh stage2
    user root
    seclabel u:r:init:s0
    oneshot
#!/system/bin/sh

SYSTEMLIB=/system/lib
if [ -d /system/lib64 ]; then
  SYSTEMLIB=/system/lib64
fi

# extract files
LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-extract $1 init.supersu.rc /sutmp/init.supersu.rc

# patch init.supersu.rc
cat /data/init.supersu.rc.patch >> /sutmp/init.supersu.rc

# push back files
LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add $1 $1 750 init.supersu.rc /sutmp/init.supersu.rc
LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add $1 $1 750 sbin/panini.sh /data/panini.sh

exit 0
CONTAINER_DEV=/dev/block/bootdevice/by-name/APD
CONTAINER_MNT=/APD
ROOT_PANINI=$CONTAINER_MNT/panini
#!/system/bin/sh
# hack for ZenFone 2 (x86)
LIB_FILES="
  lib/libc++.so
  lib/libc.so
  lib/libcutils.so
  lib/liblog.so
  lib/libm.so
  lib/libpcre.so
  lib/libselinux.so
"
if [ -d $ROOT_PANINI/lib ]; then
   for lib_file in $LIB_FILES; do
     cp -a $ROOT_MNT_SYSTEM/$lib_file $ROOT_BIND_SYSTEM/$lib_file
   done
fi
* reboot to TWRP
* adb push custom_ramdisk_patch.sh /data/
* adb push init.supersu.rc.patch /data/
* adb push panini.sh /data/
* adb shell mkdir /data/panini (optional)
* adb push config /data/panini (optional)
* adb push after_bind_tree.sh /data/panini (optional)
* adb sideload SuperSU.zip
* reboot

* put files under /APD/panini (tree structure is the same with /system)
* set right permissions (755 for directory and executable file, 644 for non-executable file)
* set right selinux context (for ex: u:object_r:dex2oat_exec:s0 for /APD/panini/bin/dex2oat..)

* for disable: touch /cache/panini.disabled
* for not updating bind tree (faster boot): touch /cache/panini.not-dirty