summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pahler <luke.linked.in+git@gmail.com>2017-10-19 11:03:27 -0600
committerLuke Pahler <luke.linked.in+git@gmail.com>2017-10-19 11:03:27 -0600
commit1908ff2864e1cc8068dfab51eefc53f96f0cdbe3 (patch)
tree069c07fbdc2dc33655d5858fcb836029fce619d1
parent1d2569958f93d6989c4940cab1bf5263c18a5963 (diff)
parent64b654a46aeb1aee4ee47d8c484a4346b9032e65 (diff)
downloadandbackup-1908ff2864e1cc8068dfab51eefc53f96f0cdbe3.tar.gz
andbackup-1908ff2864e1cc8068dfab51eefc53f96f0cdbe3.tar.xz
Merge remote-tracking branch 'origin/recovery-support'
-rwxr-xr-xandbackup.sh114
1 files changed, 80 insertions, 34 deletions
diff --git a/andbackup.sh b/andbackup.sh
index 8df40a5..7f5c239 100755
--- a/andbackup.sh
+++ b/andbackup.sh
@@ -23,6 +23,10 @@ backups=/sdcard/andbackup
#backups=/storage/ext_sd/bk/andbackup/andbackupBK
flag_delimiter="-"
+export ANDROID_DATA='/data/data'
+export ANDROID_CODE='/data/app'
+export ANDROID_SYSTEM='/system'
+
usage() {
# NOTE: The maximum width of this text should be 65 chars. This
# will ensure it displays properly on most devices without
@@ -79,48 +83,50 @@ lfatal() {
backup_app() {
- local app=${1:-}
+ local app="${1}"
- # Make sure app is specified
- if [[ -z ${app} ]]; then
- lerror "Please specify an app to backup."
+ if [ -z "${app}" ]; then
+ lerror "Application name required."
return 1
fi
#If app has the flag_delimiter that means options are passed in
local preserveCache=false
- if [[ 0 = $(echo ${app} | grep -q [${flag_delimiter}]; echo $?) ]]; then
+ if [ 0 = $(echo ${app} | grep -q [${flag_delimiter}]; echo $?) ]; then
linfo "This app $app has passed in options"
- if [[ 0 = $(echo ${app} | grep -q "preserveCache"; echo $?) ]]; then
+ if [ 0 = $(echo ${app} | grep -q "preserveCache"; echo $?) ]; then
preserveCache=true
fi
#Need to get app back to std naming (without params)
app=`echo ${app} | grep -o ^.*- | sed s/-//g | cat -`
fi
-
+
# Make sure app is installed
- if [[ $(dumpsys package ${app} | wc -l) -eq 0 ]]; then
+ if [ ! -d "${ANDROID_DATA}/${app}" ]; then
lerror "Package ${app} appears to not be installed."
return 2
fi
linfo "Backing up ${app}"
+ local apk="$(find ${ANDROID_CODE}/${app}-*/base.apk | head -n1)"
+ local data="${ANDROID_DATA}/${app}"
- # Stop the application if it is running
- am force-stop ${app}
-
- # Get pertinent metadata
- local code=$(dumpsys package ${app} | grep codePath | cut -d'=' -f2 | head -n1)
- local data=$(dumpsys package ${app} | grep dataDir | cut -d'=' -f2 | head -n1)
- #linfo HERE is your data dir: $data
+ # No need to stop the application because we're in recovery mode
# Create backup destination if not exist
- [[ ! -d ${backups} ]] && mkdir -p ${backups}
- [[ ! -d ${backups}/${app}/data ]] && mkdir -p ${backups}/${app}/data
+ [ ! -d "${backups}" ] && mkdir -p "${backups}"
+ # Delete data stage directory if it exists so we can start new
+ [ -d "${backups}/${app}/data" ] && rm -rf "${backups}/${app}/data"
# Backup the apk file if it exists
- if [[ -f ${code}/base.apk ]]; then
- cp ${code}/base.apk ${backups}/${app}/base.apk
+ if [ ! -z "${apk}" ]; then
+ # Delete the old backup first
+ # There is a permissions issue querk when the backup was originall taken in
+ # recovery mode, but later is taken in android (Permission denied for no
+ # apparent reason)
+ [ -f "${backups}/${app}/base.apk" ] && rm -f "${backups}/${app}/base.apk"
+ # Copy the installer to the backup dir
+ cp -p "${apk}" "${backups}/${app}/base.apk"
else
linfo "${app} apk file could not be found. Skipping apk installer backup."
fi
@@ -129,16 +135,26 @@ backup_app() {
# backup. This covers a weird edge case where an application is installed but
# hasn't been launched (I think?). The data variable would be empty, causing
# this script to backup /*.
- if [ ! -d "${data:-}" ] || [ -z "${data:-}" ]; then
+ if [ -z "${data}" ] || [ ! -d "${data}" ]; then
lwarn "No data directory for application '${app}' found. Skipping backup."
return 2
fi
+ # Stop the application if it is running
+ # Don't try to stop it if the twrp binary is found. If we're in recovery
+ # mode, the application already isn't running.
+ if [ ! -f /sbin/twrp ]; then
+ linfo "Stopping application ${app}"
+ am force-stop "${app}"
+ else
+ linfo "Skipping application force stop while booted to recovery mode."
+ fi
+
# Copy the user data
- cp -rp ${data}/* ${backups}/${app}/data/
+ cp -rp "${data}" "${backups}/${app}/data"
# Delete cache directory if it exists
# This will sometimes free up significant amounts of space
- if [[ ! -d "${backups}/${app}/data/cache" ]]; then
+ if [ ! -d "${backups}/${app}/data/cache" ]; then
linfo "Cache doesn't exist for ${app}"
elif ! $preserveCache; then
linfo "Deleting cache for ${app}"
@@ -149,13 +165,13 @@ backup_app() {
# Compress the backup
linfo "Compressing userdata for ${app}"
- cd ${backups}/${app}/
+ cd "${backups}/${app}/"
tar -c data | gzip -c > data.tar.gz
rm -rf data
}
-function list_apps {
+list_apps() {
pm list package | cut -d ':' -f 2 | sort
}
@@ -164,11 +180,19 @@ restore_app() {
local app=${1:-}
# Make sure app is specified
- if [[ -z ${app} ]]; then
+ if [ -z "${app}" ]; then
lerror "Please specify an app to restore."
return 1
fi
+ # If twrp binary is found on the filesystem, do not attempt restore as
+ # restores cannot be done without a running system (the various android
+ # binaries don't work right).
+ if [ -f /sbin/twrp ]; then
+ printf "Cannot perform a %s while in recovery mode.\n" "${app}"
+ return 128
+ fi
+
# When restoring something with flags need to restore app alone
if [[ 0 = $(echo ${app} | grep -q [${flag_delimiter}]; echo $?) ]]; then
linfo "This app $app had passed in options"
@@ -221,37 +245,39 @@ restore_app() {
backup_apps() {
local apps=${@}
- [[ -z ${apps[@]:-} ]] && lerror "At least one app is required." && return 1
+ [ -z "${apps}" ] && lerror "At least one app is required." && return 1
- for app in ${apps[@]}; do
- backup_app ${app}
+ IFS=' '
+ for app in ${apps}; do
+ backup_app "${app}"
done
}
restore_apps() {
local apps=${@}
- [[ -z ${apps[@]:-} ]] && log error "At least one app is required." && return 1
+ [ -z "${apps}" ] && log error "At least one app is required.\n" && return 1
- for app in ${apps[@]}; do
- restore_app ${app}
+ IFS=' '
+ for app in ${apps}; do
+ restore_app "${app}"
done
}
list_backup_apps() {
local list=${1:-}
- [[ -z ${list} ]] && printf "A backup list is required." && return 1
+ [[ -z ${list} ]] && printf "A backup list is required.\n" && return 1
for app in $(cat ${list}); do
- backup_app ${app}
+ backup_app "${app}"
done
}
list_restore_apps() {
local list=${1}
- [[ -z ${list} ]] && printf "A backup list is required." && return 1
+ [[ -z ${list} ]] && printf "A backup list is required.\n" && return 1
for app in $(cat ${list}); do
restore_app ${app}
@@ -259,6 +285,25 @@ list_restore_apps() {
}
+verify_system() {
+ if [ ! -d "${ANDROID_DATA}" ]; then
+ printf "Data directory (%s) not found.\n" ${ANDROID_DATA} >&2
+ printf "Is it mounted?\n" >&2
+ return 1
+ fi
+ if [ ! -d "${ANDROID_CODE}" ]; then
+ printf "Application code directory (%s) not found.\n" ${ANDROID_CODE} >&2
+ printf "Is it mounted?\n" >&2
+ return 1
+ fi
+ if [ ! -d "${ANDROID_SYSTEM}/etc" ]; then
+ printf "System partition (%s) is not mounted.\n" ${ANDROID_SYSTEM} >&2
+ return 1
+ fi
+ return 0
+}
+
+
main() {
local cmd=${1:-}
shift
@@ -269,6 +314,7 @@ main() {
return 1
fi
+ verify_system || return 1
if [ "${cmd}" = 'backup' ]; then
backup_apps ${@}

Generated by cgit