12/30/2011

How to backup the user info in android device

#!/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