Created
July 1, 2017 13:54
-
-
Save for2ando/28d0d6ca8dfbcaf434452c4ce2fd3265 to your computer and use it in GitHub Desktop.
Make stock recovery.img from boot (kernel) image on a Android device and several saved configuration file. Requires adb connection to the Android device.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/bash | |
progname=`basename "$0"` | |
usage="$progname check ConfDir | |
check if the current installed recovery is the stock recovery | |
which designated by the configuration. | |
$progname make ConfDir [Out] | |
make a stock recovery image file from the configuration | |
and the boot image on the phone. | |
ConfDir a directory includes install-recovery.sh and recovery-from-boot.p | |
Out file name for a recovery image made. [default=recovery.img]" | |
adbx() { | |
adb "$@" | sed -b 's/\r\r*$//' | |
} | |
adb_get_result() { | |
adbx shell "$@ >/dev/null 2>/dev/null; echo \$?" | |
} | |
adb_no_cmd() { | |
rc="`adb_get_result \"\$@\"`" | |
test "$rc" = "127" | |
} | |
readCfg() | |
{ | |
temp=$IFS | |
#Blank out the Internal Field separator (IFS) after copying it to temp. | |
IFS= | |
while read line; do | |
param=${line%=*} | |
value=${line#*=} | |
export ${param}=${value} | |
done < "$cfgfile" | |
#File read, reset IFS. | |
IFS=$temp | |
} | |
globmatch() { | |
case "$1" in | |
$2) true;; | |
*) false;; | |
esac | |
} | |
trim() { | |
sed 's/ */ /g;s/^ //;s/ $//;s/^ $//;/^$/d' | |
} | |
confirm() { | |
PS3='#? ' | |
echo "$1" | while read line | |
do | |
echo $((++i))\) $line>&2 | |
done | |
echo -n "$PS3">&2 | |
read num | |
[[ "$num" -le 0 ]] && return 2 | |
echo "$1" | sed -n "${num}p" | |
return 0 | |
} | |
if adb_no_cmd id; then | |
echo "$0: Unable to dump: No id command: I gave up.">&2 | |
exit 2 | |
elif globmatch "`adbx shell id`" 'uid=0\(*'; then | |
sucmd='' | |
elif adb_no_cmd su -c echo; then | |
echo "$0: Unable to dump: There are neither rooted adbx nor su command.">&2 | |
exit 2 | |
else | |
sucmd='su -c' | |
fi | |
adbopts="" | |
case "$1" in | |
-s|-p) adbopts="$adbopts $1 $2"; shift; shift;; | |
-*) echo "$progname: $1: unknown option.">&2; exit 2;; | |
esac | |
directive="$1" | |
if [ -z "$2" ]; then echo "$usage"; exit 0; fi | |
confdir="$2" | |
if [ -z "$3" ]; then target=recovery.img; else target="`basename $3`"; fi | |
workdir=/data/local/tmp | |
installerbase=install-recovery.sh | |
installer="$confdir/$installerbase" | |
if [ ! -f "$installer" ]; then | |
installer="$confdir/bin/$installerbase" | |
if [ ! -f "$installer" ]; then | |
installer="$confdir/etc/$installerbase" | |
if [ ! -f "$installer" ]; then | |
installer="$confdir/system/bin/$installerbase" | |
if [ ! -f "$installer" ]; then | |
installer="$confdir/system/etc/$installerbase" | |
if [ ! -f "$installer" ]; then | |
echo "$progname: installer script instal-recovery.sh not found.">&2 | |
exit 3 | |
fi | |
fi | |
fi | |
fi | |
fi | |
patchbase=recovery-from-boot.p | |
patchfile="$confdir/$patchbase" | |
if [ ! -f "$patchfile" ]; then | |
patchfile="$confdir/system/$patchbase" | |
if [ ! -f "$patchfile" ]; then | |
echo "$progname: patchfile $patchbase not found.">&2 | |
exit 4 | |
fi | |
fi | |
cfgbase=install-recovery.cfg | |
cfgfile="$confdir/$cfgbase" | |
if [ ! -f "$cfgfile" ]; then | |
cfgfile="$confdir/etc/$cfgbase" | |
if [ ! -f "$cfgfile" ]; then | |
cfgfile="$confdir/system/$cfgbase" | |
if [ ! -f "$cfgfile" ]; then | |
cfgfile="$confdir/system/etc/$cfgbase" | |
#if [ ! -f "$cfgfile" ]; then | |
#echo "$progname: cfgfile $cfgbase not found.">&2 | |
#exit 4 | |
#fi | |
fi | |
fi | |
fi | |
if [ -f "$cfgfile" ]; then | |
readCfg | |
fi | |
phones=$((`adbx devices | wc -l` - 2)) | |
if [[ $phones -le 0 ]]; then | |
echo "$progname: no adb devices. Please connect Android devices or enable adb.">&2 | |
exit 5 | |
elif [[ $phones -ge 2 ]] && ! echo "$adbopts" | fgrep -q -e ' -s ' -e ' -p '; then | |
echo "$progname: two or more adb devices connected. Disignate one device by options -s or -p as if adb command.">&2 | |
exit 6 | |
fi | |
while true; do | |
case "$directive" in | |
check) | |
cmds=`cat "$installer" | egrep 'if !? *applypatch -c ' | sed -r 's/^.*if !? *applypatch/applypatch/; s/; then$//'` | |
echo "choose a command to execution:" | |
cmd=`confirm "$cmds"` || { | |
echo "Cancelled." | |
rc=-1; break; | |
} | |
rc=`adbx shell "$cmd; echo $'\n'\\\$?" | tail -n -1` | |
echo "[result]" | |
echo "Target recovery: $confdir" | |
echo -n "Installed recovery: " | |
if [[ $rc -eq 0 ]]; then | |
echo "same as the target." | |
else | |
echo "differ from the target." | |
fi | |
;; | |
make) | |
cmds=`cat "$installer" | grep 'applypatch ' | grep -v 'applypatch -[csl] '` | |
echo "choose a base command to make:" | |
cmd=`confirm "$cmds"` || { | |
echo "Cancelled." | |
rc=-1; break; | |
} | |
case "$cmd" in *\$*) cmd=`eval echo $cmd`;; esac | |
set $cmd | |
shift | |
case "$1" in | |
-b) bonusfile="$2"; shift; shift;; | |
esac | |
cmd=" | |
cd $workdir | |
test -f "$target" || >"$target" | |
$sucmd applypatch \ | |
${bonusfile:+-b \"$bonusfile\" }\ | |
$1 \ | |
$target \ | |
$3 \ | |
$4 \ | |
${5%%:*}:$patchbase | |
" | |
cmd=`echo "$cmd" | trim` | |
echo "[copy $patchbase]" | |
( cd "$confdir"; adbx push "$patchbase" "$workdir" ) | |
echo "[command to execute on Android]" | |
echo "$cmd" | |
output=`adbx shell "$cmd; echo $'\n'\\\$?"` | |
echo "{output]" | |
echo "$output" | head -n -1 | |
rc=`echo "$output" | tail -n -1` | |
echo "[return code]" | |
echo $rc | |
[[ $rc -eq 0 ]] && { | |
echo "[copy back $target]" | |
adbx pull "$workdir/$target" . | |
} | |
;; | |
*) | |
echo "$progname: $directive: wrong directive.">&2; echo "$usage">&2; exit 2;; | |
esac | |
break | |
done | |
exit $rc |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment