Skip to content

Instantly share code, notes, and snippets.

@jyio
Created April 20, 2012 03:07
Show Gist options
  • Save jyio/2425602 to your computer and use it in GitHub Desktop.
Save jyio/2425602 to your computer and use it in GitHub Desktop.
#!/system/bin/sh
set -e
DB=/botbrew/var/lib/system-alternatives
HASHDB="${DB}/md5"
str_hash() { # <string>
echo "$1" | md5sum | awk '{ print $1 }'
}
file_hash() { # <path>
md5sum "$1" | awk '{ print $1 }'
}
master_restore() { # <master> <path-hash>
MASTER="$1"
PHASH="$2"
if [ -e "${HASHDB}/${PHASH}/master" ]; then
busybox dd if="${HASHDB}/${PHASH}/master" of="$MASTER"
if [ -e "${MASTER}" ]; then
return
else
return 1
fi
else
return 1
fi
}
master_check() { # <master> <path-hash> [<alternative>]
MASTER="$1"
PHASH="$2"
ALT="$3"
if [ -e "${MASTER}" ]; then
if [ "${ALT}" != "" ]; then
if [ -e "${ALT}" ] && [ "`file_hash "${MASTER}"`" != "`file_hash "${ALT}"`" ]; then
return 1
else
return 0
fi
else
if [ -e "${HASHDB}/${PHASH}/master" ] && [ "`file_hash "${MASTER}"`" != "`file_hash "${HASHDB}/${PHASH}/master"`" ]; then
return 1
else
return 0
fi
fi
else
if [ "${ALT}" != "" ]; then
if [ -e "${ALT}" ]; then
return 1
else
return 0
fi
else
if [ -e "${HASHDB}/${PHASH}/master" ]; then
return 1
else
return 0
fi
fi
fi
}
master_ensure() { # <master> <path-hash> [<file-hash>]
MASTER="$1"
PHASH="$2"
FHASH="$3"
if [ -e "${MASTER}" ]; then
if [ "${FHASH}" = "" ]; then FHASH=`file_hash "${MASTER}"`; fi
busybox mkdir -p "${HASHDB}/${PHASH}/history"
busybox ln -sf "${MASTER}" "${HASHDB}/${PHASH}/link"
if ! [ -e "${HASHDB}/${PHASH}/history/${FHASH}" ]; then
# master hasn't been seen before
busybox dd if="$MASTER" of="${HASHDB}/${PHASH}/master"
busybox ln -sf "../master" "${HASHDB}/${PHASH}/history/${FHASH}"
fi
elif master_restore "${MASTER}" "${PHASH}"; then
master_ensure "${MASTER}" "${PHASH}"
else
return 1
fi
}
master_clean() {
for item in "${HASHDB}/"*"/history/"*; do
if ! [ -e "${item}" ]; then
rm "${item}" || true
fi
done
}
case "$1" in
check) # <master> [<alternative>]
shift
MASTER=`busybox readlink -f "$1"`
ALT=`busybox readlink -f "$2"`
PHASH=`str_hash "${MASTER}"`
master_check "${MASTER}" "${PHASH}" "${ALT}"
;;
install) # <master> <alternative>
shift
MASTER=`busybox readlink -f "$1"`
ALT=`busybox readlink -f "$2"`
PHASH=`str_hash "${MASTER}"`
master_ensure "${MASTER}" "${PHASH}"
if [ -e "${ALT}" ]; then
FHASH=`file_hash "${ALT}"`
busybox ln -sf "${ALT}" "${HASHDB}/${PHASH}/history/${FHASH}"
busybox dd if="${ALT}" of="${MASTER}"
else
echo "${ALT}"
fi
;;
list) # <master>
shift
MASTER=`busybox readlink -f "$1"`
PHASH=`str_hash "${MASTER}"`
for item in "${HASHDB}/${PHASH}/history/"*; do
if [ -L "${item}" ]; then
echo `busybox readlink -f "${item}"`
fi
done
;;
restore) # <master>
shift
MASTER=`busybox readlink -f "$1"`
PHASH=`str_hash "${MASTER}"`
master_ensure "${MASTER}" "${PHASH}"
master_restore "${MASTER}" "${PHASH}"
rm -r "${HASHDB}/${PHASH}"
;;
clean)
master_clean
;;
selftest)
echo "\033[1m*** SELFTEST\033[0m"
TEST="/system/framework/test"
DIR="/cache/sa-test"
busybox mkdir -p "${DIR}"
echo "\033[1m*** creating test files\033[0m"
set -x
echo "test0" > "${DIR}/t0"
echo "test1" > "${DIR}/t1"
echo "test2" > "${DIR}/t2"
echo "test3" > "${DIR}/t3"
echo "test4" > "${DIR}/t4"
set +x
echo "\033[1m*** installing master file\033[0m"
set -x
cp "${DIR}/t0" "${TEST}"; cat "${TEST}"
set +x
echo "\033[1m*** installing \`t1' containing 'test1'\033[0m"
set -x
"$0" install "${TEST}" "${DIR}/t1"; cat "${TEST}"
set +x
echo "\033[1m*** installing \`t2' containing 'test2'\033[0m"
set -x
"$0" install "${TEST}" "${DIR}/t2"; cat "${TEST}"
set +x
echo "\033[1m*** known alternatives:\033[0m"
set -x
"$0" list "${TEST}"
set +x
echo "\033[1m*** checking difference between master and \`t1'\033[0m"
set -x
"$0" check "${TEST}" "${DIR}/t1" && echo "same" || echo "different"
set +x
echo "\033[1m*** checking difference between master and \`t2'\033[0m"
set -x
"$0" check "${TEST}" "${DIR}/t2" && echo "same" || echo "different"
set +x
echo "\033[1m*** checking difference between master and backup\033[0m"
set -x
"$0" check "${TEST}" && echo "same" || echo "different"
set +x
echo "\033[1m*** restoring master file\033[0m"
set -x
"$0" restore "${TEST}"; cat "${TEST}"
set +x
echo "\033[1m*** installing test files\033[0m"
set -x
"$0" install "${TEST}" "${DIR}/t1"
"$0" install "${TEST}" "${DIR}/t2"
cat "${TEST}"
set +x
echo "\033[1m*** known alternatives:\033[0m"
set -x
"$0" list "${TEST}"
set +x
echo "\033[1m*** updating master file\033[0m"
set -x
cp "${DIR}/t3" "${TEST}"; cat "${TEST}"
set +x
echo "\033[1m*** restoring master file\033[0m"
set -x
"$0" restore "${TEST}"; cat "${TEST}"
set +x
echo "\033[1m*** updating master file\033[0m"
set -x
cp "${DIR}/t3" "${TEST}"; cat "${TEST}"
set +x
echo "\033[1m*** installing \`t4' containing 'test4'\033[0m"
set -x
"$0" install "${TEST}" "${DIR}/t4"; cat "${TEST}"
set +x
echo "\033[1m*** restoring master file\033[0m"
set -x
"$0" restore "${TEST}"; cat "${TEST}"
set +x
echo "\033[1m*** cleaning up\033[0m"
set -x
rm -r "${DIR}"
"$0" clean
set +x
echo "\033[1m*** known alternatives:\033[0m"
set -x
"$0" list "${TEST}"
set +x
rm "${TEST}"
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment