#!/sbin/sh # AnyKernel3 Backend (DO NOT CHANGE) # osm0sis @ xda-developers OUTFD=/proc/self/fd/$2; ZIPFILE="$3"; ps | grep zygote | grep -v grep >/dev/null && BOOTMODE=true || BOOTMODE=false; $BOOTMODE || ps -A 2>/dev/null | grep zygote | grep -v grep >/dev/null && BOOTMODE=true; $BOOTMODE && DIR=/sdcard || DIR=$(dirname "$ZIPFILE"); test "$ANDROID_ROOT" || ANDROID_ROOT=/system; test "$home" || home=/tmp/anykernel; ui_print() { until [ ! "$1" ]; do echo -e "ui_print $1\nui_print" > $OUTFD; shift; done; } ui_printfile() { while IFS='' read -r line || $bb [[ -n "$line" ]]; do ui_print "$line"; done < $1; } show_progress() { echo "progress $1 $2" > $OUTFD; } file_getprop() { $bb grep "^$2=" "$1" | $bb cut -d= -f2-; } int2ver() { if [ "$1" -eq "$1" ] 2>/dev/null; then echo "$1.0.0"; elif [ ! "$(echo "$1" | $bb cut -d. -f3)" ]; then echo "$1.0"; else echo "$1"; fi; } cleanup() { cd $(dirname $home); rm -rf $home; } debugging() { case $(basename "$ZIPFILE" .zip) in *-debugging) ui_print " " "Creating debugging archive in $DIR..."; test -f /tmp/recovery.log && log=/tmp/recovery.log; $bb tar -czf "$DIR/anykernel3-$(date +%Y-%m-%d_%H%M%S)-debug.tgz" $home $log; ;; esac; } setup_mountpoint() { test -L $1 && $bb mv -f $1 ${1}_link; if [ ! -d $1 ]; then rm -f $1; mkdir $1; fi; } is_mounted() { $bb mount | $bb grep -q " $1 "; } umount_all() { (if ! $BOOTMODE; then umount_apex; $bb umount /system; $bb umount -l /system; if [ -e /system_root ]; then $bb umount /system_root; $bb umount -l /system_root; fi; fi; umount /vendor; umount -l /vendor; if [ "$umount_data" ]; then $bb umount /data; $bb umount -l /data; fi) 2>/dev/null; } mount_apex() { test -d /system/apex || return 1; local apex dest loop minorx num; setup_mountpoint /apex; test -e /dev/block/loop1 && minorx=$(ls -l /dev/block/loop1 | $bb awk '{ print $6 }') || minorx=1; num=0; for apex in /system/apex/*; do dest=/apex/$(basename $apex .apex); test "$dest" == /apex/com.android.runtime.release && dest=/apex/com.android.runtime; mkdir -p $dest; case $apex in *.apex) $bb unzip -qo $apex apex_payload.img -d /apex; $bb mv -f /apex/apex_payload.img $dest.img; $bb mount -t ext4 -o ro,noatime $dest.img $dest 2>/dev/null; if [ $? != 0 ]; then while [ $num -lt 64 ]; do loop=/dev/block/loop$num; ($bb mknod $loop b 7 $((num * minorx)); $bb losetup $loop $dest.img) 2>/dev/null; num=$((num + 1)); $bb losetup $loop | $bb grep -q $dest.img && break; done; $bb mount -t ext4 -o ro,loop,noatime $loop $dest; if [ $? != 0 ]; then $bb losetup -d $loop 2>/dev/null; fi; fi; ;; *) $bb mount -o bind $apex $dest;; esac; done; export ANDROID_RUNTIME_ROOT=/apex/com.android.runtime; export ANDROID_TZDATA_ROOT=/apex/com.android.tzdata; export BOOTCLASSPATH=/apex/com.android.runtime/javalib/core-oj.jar:/apex/com.android.runtime/javalib/core-libart.jar:/apex/com.android.runtime/javalib/okhttp.jar:/apex/com.android.runtime/javalib/bouncycastle.jar:/apex/com.android.runtime/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/android.test.base.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar; } umount_apex() { test -d /apex || return 1; local dest loop; for dest in $($bb find /apex -type d -mindepth 1 -maxdepth 1); do if [ -f $dest.img ]; then loop=$($bb mount | $bb grep $dest | $bb cut -d" " -f1); fi; ($bb umount -l $dest; $bb losetup -d $loop) 2>/dev/null; done; rm -rf /apex; unset ANDROID_RUNTIME_ROOT ANDROID_TZDATA_ROOT BOOTCLASSPATH; } restore_env() { test "$savedpath" && export LD_LIBRARY_PATH="$savedpath"; test "$savedpre" && export LD_PRELOAD="$savedpre"; umount_all; ($bb mv -f /apex_link /apex; $bb mv -f /system_link /system; $bb mv -f /system_root_link /system_root; $bb umount -l /dev/random) 2>/dev/null; } abort() { ui_print "$@"; debugging; restore_env; if [ ! -f anykernel.sh -o "$(file_getprop anykernel.sh do.cleanuponabort 2>/dev/null)" == 1 ]; then cleanup; fi; exit 1; } show_progress 1.34 4; ui_print " "; cleanup; mkdir -p $home/bin; cd $home; unzip -o "$ZIPFILE"; if [ $? != 0 -o ! "$(ls tools)" ]; then abort "Unzip failed. Aborting..."; fi; for arch32 in x86 arm; do if [ -d $home/tools/$arch32 ]; then bb=$home/tools/$arch32/busybox; chmod 755 $bb; $bb >/dev/null 2>&1; if [ $? == 0 ]; then $bb mv -f $home/tools/$arch32/* $home/tools; break; fi; fi; done; bb=$home/tools/busybox; chmod 755 $bb; $bb chmod -R 755 tools bin; $bb --install -s bin; if [ $? != 0 -o -z "$(ls bin)" ]; then abort "Busybox setup failed. Aborting..."; fi; ui_print " "; ui_print "================================= "; ui_print " "; ui_print " - $(file_getprop /tmp/anykernel/anykernel.sh kernel.string)"; ui_print " "; ui_print "================================= "; ui_print " "; if [ -f version ]; then ui_print " "; ui_printfile version; ui_print " "; fi; ui_print " - AnyKernel3 by osm0sis "; $BOOTMODE || $bb mount -o bind /dev/urandom /dev/random; umount_all; setup_mountpoint $ANDROID_ROOT; if ! is_mounted $ANDROID_ROOT; then $bb mount -o ro -t auto $ANDROID_ROOT; fi; case $ANDROID_ROOT in /system_root) setup_mountpoint /system;; /system) if [ -f /system/system/build.prop ]; then setup_mountpoint /system_root; $bb mount --move /system /system_root; if [ $? != 0 ]; then $bb umount /system; $bb umount -l /system 2>/dev/null; $bb mount -o ro -t auto /dev/block/bootdevice/by-name/system /system_root; fi; fi; ;; esac; if is_mounted /system_root; then $bb mount -o bind /system_root/system /system; fi; $bb mount -o ro -t auto /vendor 2>/dev/null; $BOOTMODE || mount_apex; if ! is_mounted /data; then $bb mount /data; umount_data=1; fi; savedpath="$LD_LIBRARY_PATH"; savedpre="$LD_PRELOAD"; unset LD_LIBRARY_PATH; unset LD_PRELOAD; if [ ! "$(getprop 2>/dev/null)" ]; then getprop() { local propdir propfile propval; for propdir in / /system_root /system /vendor /odm /product; do for propfile in default.prop build.prop; do test "$propval" && break 2 || propval="$(file_getprop $propdir/$propfile $1 2>/dev/null)"; done; done; test "$propval" && echo "$propval" || echo ""; } elif [ ! "$(getprop ro.build.type 2>/dev/null)" ]; then getprop() { ($(which getprop) | $bb grep "$1" | $bb cut -d[ -f3 | $bb cut -d] -f1) 2>/dev/null; } fi; if [ "$(file_getprop anykernel.sh do.devicecheck)" == 1 ]; then ui_print " - Checking device..."; device=$(getprop ro.product.device 2>/dev/null); product=$(getprop ro.build.product 2>/dev/null); vendordevice=$(getprop ro.product.vendor.device 2>/dev/null); vendorproduct=$(getprop ro.vendor.product.device 2>/dev/null); for testname in $(file_getprop anykernel.sh 'device.name.*'); do for devicename in $device $product $vendordevice $vendorproduct; do if [ "$devicename" == "$testname" ]; then ui_print " - Device: $testname"; match=1; break 2; fi; done; done; if [ ! "$match" ]; then abort " - Unsupported device. Aborting..."; fi; fi; supported_ver=$(file_getprop anykernel.sh supported.versions | $bb tr -d '[:space:]'); if [ "$supported_ver" ]; then ui_print " - Checking Android version..."; android_ver=$(file_getprop /system/build.prop ro.build.version.release); parsed_ver=$(int2ver $android_ver); if echo $supported_ver | $bb grep -q '-'; then lo_ver=$(int2ver "$(echo $supported_ver | $bb cut -d- -f1)"); hi_ver=$(int2ver "$(echo $supported_ver | $bb cut -d- -f2)"); if echo -e "$hi_ver\n$lo_ver\n$parsed_ver" | $bb sort -g | $bb grep -n "$parsed_ver" | $bb grep -q '^2:'; then supported=1; fi; else for ver in $(echo $supported_ver | $bb sed 's;,; ;g'); do if [ "$(int2ver $ver)" == "$parsed_ver" ]; then supported=1; break; fi; done; fi; if [ "$supported" ]; then ui_print " - Android Version: $android_ver"; else abort " - Unsupported Android version. Aborting..."; fi; fi; supported_lvl=$(file_getprop anykernel.sh supported.patchlevels | $bb grep -oE '[0-9]{4}-[0-9]{2}|-'); if [ "$supported_lvl" ]; then ui_print " - Checking Android security patch level..."; android_lvl=$(file_getprop /system/build.prop ro.build.version.security_patch); parsed_lvl=$(echo $android_lvl | $bb grep -oE '[0-9]{4}-[0-9]{2}'); if echo $supported_lvl | $bb grep -q '^\-'; then lo_lvl=0000-00; hi_lvl=$(echo $supported_lvl | $bb awk '{ print $2 }'); elif echo $supported_lvl | $bb grep -q ' - '; then lo_lvl=$(echo $supported_lvl | $bb awk '{ print $1 }'); hi_lvl=$(echo $supported_lvl | $bb awk '{ print $3 }'); elif echo $supported_lvl | $bb grep -q '\-$'; then lo_lvl=$(echo $supported_lvl | $bb awk '{ print $1 }'); hi_lvl=9999-99; fi; if echo -e "$hi_lvl\n$lo_lvl\n$parsed_lvl" | $bb sort -g | $bb grep -n "$parsed_lvl" | $bb grep -q '^2:'; then ui_print "$android_lvl" " "; else abort " - Unsupported Android security patch level. Aborting..."; fi; fi; ui_print " - Installing kernel..."; core=$($bb grep -oE 'ak.*core.sh' anykernel.sh); test -f tools/$core || $bb ln -s $home/tools/ak*-core.sh $home/tools/$core; PATH="$home/bin:$PATH" home=$home $bb ash anykernel.sh $2; if [ $? != 0 ]; then abort; fi; if [ "$(file_getprop anykernel.sh do.modules)" == 1 ]; then ui_print " - Pushing modules..."; $bb mount -o rw,remount -t auto /system; $bb mount -o rw,remount -t auto /vendor 2>/dev/null; cd $home/modules; for module in $(find . -name '*.ko'); do modtarget=$(echo $module | $bb cut -c2-); if [ ! -e $modtarget ]; then case $module in */vendor/*) modcon=vendor;; *) modcon=system;; esac; fi; if is_mounted $modtarget; then $bb mount -o rw,remount -t auto $modtarget; fi; mkdir -p $(dirname $modtarget); $bb cp -rLf $module $modtarget; $bb chown 0:0 $modtarget; $bb chmod 644 $modtarget; if [ "$modcon" ]; then chcon "u:object_r:${modcon}_file:s0" $modtarget; fi; if is_mounted $modtarget; then $bb mount -o ro,remount -t auto $modtarget; fi; done; cd $home; $bb mount -o ro,remount -t auto /system; $bb mount -o ro,remount -t auto /vendor 2>/dev/null; fi; debugging; restore_env; if [ "$(file_getprop anykernel.sh do.cleanup)" == 1 ]; then ui_print " - Cleaning up..."; cleanup; fi; ui_print " - Done!";