extract-utils: Add pinning support
* In many cases, we would like to keep certain files which do not exactly match what might be extracted from a factory ROM. This becomes extremely annoying over time to manually reconstruct, and it's easy to miss these special cases when updating to a new vendor release. It's also useful to flag additions which aren't found in the upstream release at all. * To solve this, we can now "pin" files to a specific sha1 hash. Simply append the sha1sum of the file to the appropriate line in your bloblist, prepended by a | delimiter. * This works by backing up the current files first, running the extraction, then checking if any pinned files need to be restored. * Also add an exit trap to clean up all of our tempfiles Change-Id: I2010b5175b5701e19a3efb112e8907062ca37d66
This commit is contained in:
parent
049d4c52be
commit
48f8df8ddb
|
@ -16,7 +16,9 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
PRODUCT_COPY_FILES_LIST=()
|
PRODUCT_COPY_FILES_LIST=()
|
||||||
|
PRODUCT_COPY_FILES_HASHES=()
|
||||||
PRODUCT_PACKAGES_LIST=()
|
PRODUCT_PACKAGES_LIST=()
|
||||||
|
PRODUCT_PACKAGES_HASHES=()
|
||||||
PACKAGE_LIST=()
|
PACKAGE_LIST=()
|
||||||
VENDOR_STATE=-1
|
VENDOR_STATE=-1
|
||||||
VENDOR_RADIO_STATE=-1
|
VENDOR_RADIO_STATE=-1
|
||||||
|
@ -27,6 +29,17 @@ FULLY_DEODEXED=-1
|
||||||
TMPDIR="/tmp/extractfiles.$$"
|
TMPDIR="/tmp/extractfiles.$$"
|
||||||
mkdir "$TMPDIR"
|
mkdir "$TMPDIR"
|
||||||
|
|
||||||
|
#
|
||||||
|
# cleanup
|
||||||
|
#
|
||||||
|
# kill our tmpfiles with fire on exit
|
||||||
|
#
|
||||||
|
function cleanup() {
|
||||||
|
rm -rf "${TMPDIR:?}"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT INT TERM ERR
|
||||||
|
|
||||||
#
|
#
|
||||||
# setup_vendor
|
# setup_vendor
|
||||||
#
|
#
|
||||||
|
@ -510,16 +523,31 @@ function parse_file_list() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PRODUCT_PACKAGES_LIST=()
|
PRODUCT_PACKAGES_LIST=()
|
||||||
|
PRODUCT_PACKAGES_HASHES=()
|
||||||
PRODUCT_COPY_FILES_LIST=()
|
PRODUCT_COPY_FILES_LIST=()
|
||||||
|
PRODUCT_COPY_FILES_HASHES=()
|
||||||
|
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
if [ -z "$line" ]; then continue; fi
|
if [ -z "$line" ]; then continue; fi
|
||||||
|
|
||||||
|
# If the line has a pipe delimiter, a sha1 hash should follow.
|
||||||
|
# This indicates the file should be pinned and not overwritten
|
||||||
|
# when extracting files.
|
||||||
|
local SPLIT=(${line//\|/ })
|
||||||
|
local COUNT=${#SPLIT[@]}
|
||||||
|
local SPEC=${SPLIT[0]}
|
||||||
|
local HASH="x"
|
||||||
|
if [ "$COUNT" -gt "1" ]; then
|
||||||
|
HASH=${SPLIT[1]}
|
||||||
|
fi
|
||||||
|
|
||||||
# if line starts with a dash, it needs to be packaged
|
# if line starts with a dash, it needs to be packaged
|
||||||
if [[ "$line" =~ ^- ]]; then
|
if [[ "$SPEC" =~ ^- ]]; then
|
||||||
PRODUCT_PACKAGES_LIST+=("${line#-}")
|
PRODUCT_PACKAGES_LIST+=("${SPEC#-}")
|
||||||
|
PRODUCT_PACKAGES_HASHES+=("$HASH")
|
||||||
else
|
else
|
||||||
PRODUCT_COPY_FILES_LIST+=("$line")
|
PRODUCT_COPY_FILES_LIST+=("$SPEC")
|
||||||
|
PRODUCT_COPY_FILES_HASHES+=("$HASH")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
done < <(egrep -v '(^#|^[[:space:]]*$)' "$1" | sort | uniq)
|
done < <(egrep -v '(^#|^[[:space:]]*$)' "$1" | sort | uniq)
|
||||||
|
@ -621,6 +649,10 @@ function oat2dex() {
|
||||||
FULLY_DEODEXED=1 && return 0 # system is fully deodexed, return
|
FULLY_DEODEXED=1 && return 0 # system is fully deodexed, return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$CM_TARGET" ]; then
|
||||||
|
return;
|
||||||
|
fi
|
||||||
|
|
||||||
if grep "classes.dex" "$CM_TARGET" >/dev/null; then
|
if grep "classes.dex" "$CM_TARGET" >/dev/null; then
|
||||||
return 0 # target apk|jar is already odexed, return
|
return 0 # target apk|jar is already odexed, return
|
||||||
fi
|
fi
|
||||||
|
@ -708,16 +740,21 @@ function extract() {
|
||||||
set +e
|
set +e
|
||||||
|
|
||||||
local FILELIST=( ${PRODUCT_COPY_FILES_LIST[@]} ${PRODUCT_PACKAGES_LIST[@]} )
|
local FILELIST=( ${PRODUCT_COPY_FILES_LIST[@]} ${PRODUCT_PACKAGES_LIST[@]} )
|
||||||
|
local HASHLIST=( ${PRODUCT_COPY_FILES_HASHES[@]} ${PRODUCT_PACKAGES_HASHES[@]} )
|
||||||
local COUNT=${#FILELIST[@]}
|
local COUNT=${#FILELIST[@]}
|
||||||
local SRC="$2"
|
local SRC="$2"
|
||||||
local OUTPUT_ROOT="$CM_ROOT"/"$OUTDIR"/proprietary
|
local OUTPUT_ROOT="$CM_ROOT"/"$OUTDIR"/proprietary
|
||||||
|
local OUTPUT_TMP="$TMPDIR"/"$OUTDIR"/proprietary
|
||||||
|
|
||||||
if [ "$SRC" = "adb" ]; then
|
if [ "$SRC" = "adb" ]; then
|
||||||
init_adb_connection
|
init_adb_connection
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$VENDOR_STATE" -eq "0" ]; then
|
if [ "$VENDOR_STATE" -eq "0" ]; then
|
||||||
echo "Cleaning output directory ($OUTPUT_ROOT).."
|
echo "Cleaning output directory ($OUTPUT_ROOT).."
|
||||||
rm -rf "${OUTPUT_ROOT:?}/"*
|
rm -rf "${OUTPUT_TMP:?}"
|
||||||
|
mkdir -p "${OUTPUT_TMP:?}"
|
||||||
|
mv "${OUTPUT_ROOT:?}/"* "${OUTPUT_TMP:?}/"
|
||||||
VENDOR_STATE=1
|
VENDOR_STATE=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -730,11 +767,13 @@ function extract() {
|
||||||
local SPLIT=(${FILELIST[$i-1]//:/ })
|
local SPLIT=(${FILELIST[$i-1]//:/ })
|
||||||
local FILE="${SPLIT[0]#-}"
|
local FILE="${SPLIT[0]#-}"
|
||||||
local OUTPUT_DIR="$OUTPUT_ROOT"
|
local OUTPUT_DIR="$OUTPUT_ROOT"
|
||||||
|
local TMP_DIR="$OUTPUT_TMP"
|
||||||
local TARGET=
|
local TARGET=
|
||||||
|
|
||||||
if [ "$ARGS" = "rootfs" ]; then
|
if [ "$ARGS" = "rootfs" ]; then
|
||||||
TARGET="$FROM"
|
TARGET="$FROM"
|
||||||
OUTPUT_DIR="$OUTPUT_DIR/rootfs"
|
OUTPUT_DIR="$OUTPUT_DIR/rootfs"
|
||||||
|
TMP_DIR="$TMP_DIR/rootfs"
|
||||||
else
|
else
|
||||||
TARGET="system/$FROM"
|
TARGET="system/$FROM"
|
||||||
FILE="system/$FILE"
|
FILE="system/$FILE"
|
||||||
|
@ -761,10 +800,13 @@ function extract() {
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Try OEM target first
|
# Try OEM target first
|
||||||
cp "$SRC/$FILE" "$DEST"
|
if [ -f "$SRC/$FILE" ]; then
|
||||||
|
cp "$SRC/$FILE" "$DEST"
|
||||||
# if file does not exist try CM target
|
# if file does not exist try CM target
|
||||||
if [ "$?" != "0" ]; then
|
elif [ -f "$SRC/$TARGET" ]; then
|
||||||
cp "$SRC/$TARGET" "$DEST"
|
cp "$SRC/$TARGET" "$DEST"
|
||||||
|
else
|
||||||
|
printf ' !! file not found in source\n'
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -782,12 +824,39 @@ function extract() {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local TYPE="${DIR##*/}"
|
# Check pinned files
|
||||||
if [ "$TYPE" = "bin" -o "$TYPE" = "sbin" ]; then
|
local HASH="${HASHLIST[$i-1]}"
|
||||||
chmod 755 "$DEST"
|
if [ ! -z "$HASH" ] && [ "$HASH" != "x" ]; then
|
||||||
else
|
local KEEP=""
|
||||||
chmod 644 "$DEST"
|
local TMP="$TMP_DIR/$FROM"
|
||||||
|
if [ -f "$TMP" ]; then
|
||||||
|
if [ ! -f "$DEST" ]; then
|
||||||
|
KEEP="1"
|
||||||
|
else
|
||||||
|
local DEST_HASH=$(sha1sum "$DEST" | awk '{print $1}' )
|
||||||
|
if [ "$DEST_HASH" != "$HASH" ]; then
|
||||||
|
KEEP="1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$KEEP" = "1" ]; then
|
||||||
|
local TMP_HASH=$(sha1sum "$TMP" | awk '{print $1}' )
|
||||||
|
if [ "$TMP_HASH" = "$HASH" ]; then
|
||||||
|
printf ' + (keeping pinned file with hash %s)\n' "$HASH"
|
||||||
|
cp -p "$TMP" "$DEST"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -f "$DEST" ]; then
|
||||||
|
local TYPE="${DIR##*/}"
|
||||||
|
if [ "$TYPE" = "bin" -o "$TYPE" = "sbin" ]; then
|
||||||
|
chmod 755 "$DEST"
|
||||||
|
else
|
||||||
|
chmod 644 "$DEST"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
# Don't allow failing
|
# Don't allow failing
|
||||||
|
|
Loading…
Reference in New Issue