#!/system/bin/sh
GetBackupList() {
RAW_LIST=`grep '<package' /data/system/packages.xml | grep "$APPS_DIR"`
COUNT=`echo "$RAW_LIST" | wc -l`
while [ "$COUNT" -gt 0 ];do
BACKUP=`echo "$RAW_LIST" | sed -n $COUNT"p" | cut -d' ' -f2 | cut -d'=' -f2 | sed 's/"//g'`
BACKUP=$BACKUP"|"`echo "$RAW_LIST" | sed -n $COUNT"p" | cut -d' ' -f3 | cut -d'=' -f2 | sed 's/"//g'`
echo $BACKUP
COUNT=$(($COUNT-1))
done
}
FILE_PREFIX="recback"
DEF_BACKUP_PATH="/sdcard"
TMP_DIR="/data/recback_dir"
TMP_FILE="$TMP_DIR/recback.tmp"
WIFI_CONF="/data/misc/wifi/wpa_supplicant.conf"
APPS_DIR="/data/app"
DATA_DIR="/data/data"
TIMEOUT="10"
# the providers which will be backup or restored
PROVIDERS="
com.android.providers.calendar
com.android.providers.telephony
com.android.providers.contacts
com.android.providers.settings
"
if [ ! -d "$TMP_DIR" ];then
mkdir $TMP_DIR
fi
if [ "$1" == "-r" ];then
shift
if [ -z "$1" ];then
echo "Expect parameter: Need to specify the backup file"
return 1
fi
if [ ! -r "$1" ];then
echo "Expect a readable backup file"
return 1
fi
BACKUP_FILE="$1"
echo "Restoring..."
GetBackupList > "$TMP_FILE"
# ========= Restore APKs =============
TAR_APKS=`tar -tvf $BACKUP_FILE | grep '.apk' | sed 's/[ ][ ][ ]*/ /g' | \
cut -d' ' -f6`
# Remove old apks and data
for TAR_APK in $TAR_APKS;do
# To avoid the name of *-1.apk
APK_REAL_NAME=${TAR_APK%.*} # exclude the extension name
if [ $(echo ${APK_REAL_NAME##*-} | grep -E "[^0-9]" -v -c) -ne 0 ];then
# This case means the file name is formatted as *-[0-9] with the
# numbered postfix, so we should change the name to real name
APK_REAL_NAME=${APK_REAL_NAME%-*} # exclude the numbered postfix
fi
if [ -f "/$APK_REAL_NAME"-*.apk ];then
APK_DATA_PATH="$DATA_DIR/"`cat "$TMP_FILE" | grep "$APK_REAL_NAME" | \
cut -d'|' -f1`
if [ -d "$APK_DATA_PATH" ];then
rm -r $APK_DATA_PATH
fi
rm "/$APK_REAL_NAME"-*.apk
fi
done
PRE_CD=`pwd`
cd $TMP_DIR
for TAR_APK in $TAR_APKS;do
tar -xvf $BACKUP_FILE $TAR_APK
# To avoid the name of *-1.apk
APK_REAL_NAME=${TAR_APK%.*} # exclude the extension name
if [ $(echo ${APK_REAL_NAME##*-} | grep -E "[^0-9]" -v -c) -ne 0 ];then
# This case means the file name is formatted as *-[0-9] with the
# numbered postfix, so we should change the name to real name
APK_REAL_NAME=${APK_REAL_NAME%-*} # exclude the numbered postfix
mv $TAR_APK $APK_REAL_NAME".apk"
TAR_APK=$APK_REAL_NAME".apk"
fi
cp -f $TAR_APK "$APPS_DIR" # install the apk
rm $TAR_APK
PKG_NAME=`grep '<package' /data/system/packages.xml | grep "$TAR_APK" | \
cut -d' ' -f2 | cut -d'=' -f2 | sed 's/"//g'`
NATIVE_LIB=`grep '<package' /data/system/packages.xml | grep "$TAR_APK" | \
cut -d' ' -f4 | cut -d'=' -f2 | sed 's/"//g'`
TIMEOUT="10"
while [ -z "$PKG_NAME" ] || [ -z "$NATIVE_LIB" ];do
echo "wait system update $PKG_NAME ..."
sleep 1
PKG_NAME=`grep '<package' /data/system/packages.xml | grep "$TAR_APK" | \
cut -d' ' -f2 | cut -d'=' -f2 | sed 's/"//g'`
NATIVE_LIB=`grep '<package' /data/system/packages.xml | grep "$TAR_APK" | \
cut -d' ' -f4 | cut -d'=' -f2 | sed 's/"//g'`
if [ $TIMEOUT -gt 0 ];then
TIMEOUT=$(($TIMEOUT-1))
else
rm "/$TAR_APK"
break
fi
done
if [ -n "$PKG_NAME" ];then
DATA_OWN=`ls -l $DATA_DIR | grep "$PKG_NAME" | sed 's/\t/ /g' | \
sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f2`
DATA_GROUP=`ls -l $DATA_DIR | grep "$PKG_NAME" | sed 's/\t/ /g' | \
sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f3`
if [ -z "$DATA_OWN" ] || [ -z "$DATA_GROUP" ];then
BEGIN_INDEX="5"
while [ $(echo $DATA_OWN | grep "userId" -c) -eq 0 ] && \
[ $(echo $DATA_OWN | grep "sharedUserId" -c) -eq 0 ];do
DATA_OWN=`grep '<package' /data/system/packages.xml | \
grep "$TAR_APK" | cut -d' ' -f"$BEGIN_INDEX"`
BEGIN_INDEX=$(($BEGIN_INDEX+1))
done
DATA_OWN=`echo $DATA_OWN | cut -d'=' -f2 | sed 's/"//g' | sed 's/\>//g'`
DATA_GROUP="$DATA_OWN"
fi
echo "tar $BACKUP_FILE data/data/$PKG_NAME"
tar -xvf $BACKUP_FILE "data/data/$PKG_NAME"
echo "Copy data/data/$PKG_NAME"
if [ -d "$DATA_DIR/$PKG_NAME/lib" ];then
rm -r "data/data/$PKG_NAME/lib"
fi
cp -rf "data/data/$PKG_NAME" "$DATA_DIR/"
rm -r "data/data/$PKG_NAME" # delete immediately for more free space
echo "pkgname: $PKG_NAME | lib: $NATIVE_LIB | own: $DATA_OWN | group: $DATA_GROUP"
# Get each package data file and change the own permission to current apk
PKG_DATA_FILES=`find $DATA_DIR/$PKG_NAME`
chown $DATA_OWN"."$DATA_GROUP $PKG_DATA_FILES
PKG_LIB_FILES=`find $NATIVE_LIB`
chown "system.system" $PKG_LIB_FILES
else
# need to do sth?
echo "ERROR: install $TAR_APK failed, PKG_NAME null"
fi
done
# ========= End of restore APKs =============
# ========= Restore Wifi configuration =============
if [ ! -d "/data/misc" ];then
mkdir /data/misc
fi
if [ ! -d "/data/misc/wifi" ];then
mkdir /data/misc/wifi
fi
tar -xvf $BACKUP_FILE "data/misc/wifi/wpa_supplicant.conf"
cp -f data/misc/wifi/wpa_supplicant.conf /data/misc/wifi/
chown "wifi.wifi" /data/misc/wifi/wpa_supplicant.conf
# ========= End of restore Wifi configuration =============
# ========= Restore Providers =============
# backup origin providers
PROVIDER_LIST=""
for PROVIDER in $PROVIDERS;do
if [ -d "$DATA_DIR/$PROVIDER" ];then
PROVIDER_LIST="$PROVIDER_LIST $DATA_DIR/$PROVIDER"
else
echo "ERROR: the provider [$PROVIDER] not existed"
fi
done
tar -cvf $DEF_BACKUP_PATH"/providers_"$TIME_STAMP".tar" $PROVIDER_LIST
TAR_PROVIDERS=`tar -tvf $BACKUP_FILE | \
grep 'com.android.providers.*/databases/' | \
grep "^d" | sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f6`
for TAR_PROVIDER in $TAR_PROVIDERS;do
tar -xvf $BACKUP_FILE $TAR_PROVIDER
if [ ! -d "/$TAR_PROVIDER" ];then
echo "skipped /$TAR_PROVIDER"
continue
fi
DATA_OWN=`ls -l /$TAR_PROVIDER | head -n1 | sed 's/\t/ /g' | \
sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f2`
DATA_GROUP=`ls -l /$TAR_PROVIDER | head -n1 | sed 's/\t/ /g' | \
sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f3`
echo "Copy $TAR_PROVIDER"
cp -rf $TAR_PROVIDER/* "/$TAR_PROVIDER"
DATABASES_FILES=`find /$TAR_PROVIDER`
chown "$DATA_OWN.$DATA_GROUP" $DATABASES_FILES
rm -r $TAR_PROVIDER
done
# ========= End of restore Providers =============
rm "$TMP_FILE"
cd "$PRE_CD"
elif [ "$1" == "-b" ];then
echo "Begin backup: $TIME_STAMP"
GetBackupList > "$TMP_FILE"
BACKUP_LIST=`cat "$TMP_FILE" | cut -d'|' -f1 | sed 's/^/\/data\/data\//g'`
PROVIDER_LIST=""
for PROVIDER in $PROVIDERS;do
if [ -d "$DATA_DIR/$PROVIDER/databases" ];then
PROVIDER_LIST="$PROVIDER_LIST $DATA_DIR/$PROVIDER/databases"
else
echo "ERROR: the provider [$PROVIDER] not existed"
fi
done
TIME_STAMP=`date "+%y%m%d%H%M%S"`
if [ ! -f "$WIFI_CONF" ];then
WIFI_CONF=""
fi
if [ ! -d "$APPS_DIR" ];then
APPS_DIR=""
fi
PRE_CD=`pwd`
cd "/data"
tar -cvf $DEF_BACKUP_PATH"/"$FILE_PREFIX$TIME_STAMP".tar" \
$BACKUP_LIST $PROVIDER_LIST $WIFI_CONF $APPS_DIR
echo "Done: "$DEF_BACKUP_PATH"/"$FILE_PREFIX$TIME_STAMP".tar"
cd "$PRE_CD"
rm "$TMP_FILE"
elif [ "$1" == "-l" ];then
ls -l $DEF_BACKUP_PATH/$FILE_PREFIX*.tar | sed 's/\t/ /g' | sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f7 | sed "s/^/\/sdcard\//g"
else
echo "Useage: recback.sh <option> [file]"
echo " -b backup user data"
echo " -r <file> restore the specified backup file"
echo " -l list the backup files in default path"
echo " default backup path: /sdcard"
fi
rm -r "$TMP_DIR"
No comments:
Post a Comment