Skip to content

Instantly share code, notes, and snippets.

@for2ando
Created July 1, 2017 13:54
Show Gist options
  • Save for2ando/28d0d6ca8dfbcaf434452c4ce2fd3265 to your computer and use it in GitHub Desktop.
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.
#!/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