Skip to content

Commit

Permalink
Remove Inquirer.sh dependency
Browse files Browse the repository at this point in the history
Inquirer.sh is unmaintained and has been causing issues for a very long time. This commit replaces it with Whiptail or dialog on macOS. Fixes mrrfv#59

Version 1.0.7
  • Loading branch information
mrrfv committed May 12, 2023
1 parent 3ece0fb commit 1818aa4
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 1,640 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ These things are the majority of what most people would want to keep safe, but e

### Linux

1. Install p7zip, adb, curl, bc, pv and optionally secure-delete. If you're on Debian or Ubuntu, run this command: `sudo apt update; sudo apt install p7zip-full adb curl bc pv secure-delete`.
1. Install p7zip, adb, curl, whiptail, pv and optionally secure-delete. If you're on Debian or Ubuntu, run this command: `sudo apt update; sudo apt install p7zip-full adb curl whiptail pv secure-delete`.
2. [Download](https://github.com/mrrfv/open-android-backup/releases/latest) the Open Android Backup bundle, which contains the script and companion app in one package. You can also grab an experimental build (heavily discouraged) by clicking on [this link](https://github.com/mrrfv/open-android-backup/archive/refs/heads/master.zip) or cloning.
3. Enable [developer options](https://developer.android.com/studio/debug/dev-options#enable) and USB debugging on your device, then run `backup.sh` in a terminal.

Expand All @@ -59,7 +59,7 @@ These things are the majority of what most people would want to keep safe, but e
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# If you already have Homebrew installed, just run these 2 commands:
brew install --cask android-platform-tools
brew install p7zip pv bash
brew install p7zip pv bash dialog
```

2. Follow the steps 2 and 3 from the install guide for Linux.
Expand Down
2 changes: 1 addition & 1 deletion backup-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ wsl --shutdown
wsl sudo apt update
wsl sudo apt dist-upgrade -y
Write-Output "Installing dependencies and setting up environment..."
wsl sudo apt install p7zip-full secure-delete curl bc dos2unix pv kdialog '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev -y
wsl sudo apt install p7zip-full secure-delete whiptail curl dos2unix pv kdialog '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev -y
Write-Output "Converting files - this may take several minutes..."
wsl bash -c "sudo find ./ -name '*.sh' -type f -print0 | sudo xargs -0 dos2unix --"
Clear-Host
Expand Down
44 changes: 35 additions & 9 deletions backup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,30 @@ set -e
# Application metadata - don't change
# This is used to download a stable, compatible version of the Android companion app as well as ensure backwards compatibility,
# so it should match the tag name in GitHub Releases.
APP_VERSION="v1.0.4"
APP_VERSION="v1.0.7"

# We use whiptail for showing dialogs.
# Whiptail is used similarly as dialog, but we can't install it on macOS using Homebrew IIRC.
# So we need to fall back to dialog if whiptail is not available.
# Check if whiptail is installed
if command -v whiptail &> /dev/null; then
# Whiptail is installed, no action needed. Do nothing.
:
else
# Check if dialog is installed
if command -v dialog &> /dev/null; then
echo "Whiptail is not installed, but dialog is. Defining whiptail as a function that calls dialog."
# Define whiptail as a function that calls dialog with the same arguments
whiptail() {
dialog "$@"
}
else
# Neither whiptail nor dialog are installed
echo "Error: Neither whiptail nor dialog are installed. Exiting."
exit 1
fi
fi


SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
Expand All @@ -14,9 +37,6 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

# Load Inquirer.sh
source "$DIR/inquirer-sh/list_input.sh"
source "$DIR/inquirer-sh/text_input.sh"
# ---

# Load all functions in ./functions
Expand All @@ -26,7 +46,7 @@ check_adb_connection

if [ ! -v mode ]; then
modes=( 'Wired' 'Wireless' )
list_input "Connection method:" modes mode
select_option_from_list "Choose the connection method. Wireless is experimental and still requires a device connected for pairing." modes[@] mode
fi

if [ "$mode" = 'Wireless' ]; then
Expand All @@ -40,9 +60,11 @@ if [ ! -v export_method ]; then
cecho "Choose the exporting method."
cecho "- Pick 'tar' first, as it is fast and most reliable, but might not work on all devices."
cecho "- If the script crashes, pick 'adb' instead, which works on all devices."
cecho "Press Enter to pick your preferred method."
wait_for_enter

export_methods=( 'tar' 'adb' )
list_input "Exporting method:" export_methods export_method
select_option_from_list "Choose the exporting method." export_methods[@] export_method
fi

clear
Expand All @@ -53,9 +75,11 @@ if [ ! -v use_hooks ]; then
cecho "Choose 'yes' if you have installed your own hooks and would like to use them."
cecho "Read README.md for more information."
cecho "USING HOOKS IS A SECURITY RISK! THEY HAVE THE EXACT SAME PERMISSIONS AS THIS SCRIPT, AND THUS CAN WIPE YOUR ENTIRE DEVICE OR SEND ALL YOUR DATA TO A REMOTE SERVER. If you are selecting 'yes', please make sure that you have read and understood the code in hooks.sh."
cecho "Press Enter to choose."
wait_for_enter

should_i_use_hooks=( 'no' 'yes' )
list_input "Use hooks:" should_i_use_hooks use_hooks
select_option_from_list "Use hooks? Pick No if unsure or security-conscious." should_i_use_hooks[@] use_hooks
fi

clear
Expand All @@ -80,9 +104,11 @@ then
cecho "The options below allow you to securely erase this data, making it harder for law enforcement and other adversaries to view your files."
cecho "Your choice will also apply to cleanups, i.e. if the script has previously crashed without removing the files."
cecho "Fast is considered insecure and can only be recommended on encrypted disks. Slow takes more time than the former, and it's safe enough for most people (2 passes). Extra Slow is only recommended for the paranoid (Gutmann method)."
cecho "Press Enter to pick your data erase mode."
wait_for_enter

data_erase_choices=( "Fast" "Slow" "Extra Slow" )
list_input "Data Erase Mode:" data_erase_choices data_erase_choice
select_option_from_list "Choose the Data Erase Mode." data_erase_choices[@] data_erase_choice

clear
fi
Expand All @@ -93,7 +119,7 @@ fi

if [ ! -v selected_action ]; then
actions=( 'Backup' 'Restore' )
list_input "What do you want to do?" actions selected_action
select_option_from_list "What do you want to do?" actions[@] selected_action
fi

# The companion app is required regardless of whether we're backing up the device or not,
Expand Down
8 changes: 5 additions & 3 deletions functions/backup_func.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
function backup_func() {
while true; do
if [ ! -v archive_path ]; then
echo "Note: Backups will first be made on the drive this script is located in, and then will be copied to the specified location."

# Check if we're running on Windows.
# If we are, then we will open a file chooser instead of asking the user for the file path thru CLI
# due to compatibility issues.
Expand All @@ -17,7 +15,11 @@ function backup_func() {
wait_for_enter
archive_path=$(kdialog --getexistingdirectory /mnt/c 2>/dev/null | tail -n 1 | sed 's/\r$//' || true)
else
text_input "Please enter the backup location. Enter '.' for the current working directory." archive_path "."
get_text_input \
"Please enter the backup location. Enter '.' for the current working directory.
Note: Backups will first be made on the drive this script is located in, and then will be copied to the specified location." \
archive_path \
"."
fi

fi
Expand Down
74 changes: 73 additions & 1 deletion functions/helper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,83 @@ function install_companion_app() {
)
# Grant permissions
for permission in "${permissions[@]}"; do
adb shell pm grant mrrfv.backup.companion "$permission" || cecho "Couldn't assign permission $permission to the companion app - this is not a fatal error, and you will just have to allow this permission in the app." 1>&2
adb shell pm grant mrrfv.backup.companion "$permission" || cecho "Couldn't assign permission $permission to the companion app - this is not a fatal error, and you will just have to allow this permission in the app." 1>&2
done
fi
}

# A function that takes a prompt, an array of options, and a result variable as arguments
# and uses whiptail to display a menu for selecting an option
# The selected option is stored in the result variable
# If no option is selected or an error occurs, the function exits with an error message
function select_option_from_list() {
# Check if the number of arguments is 3
if [[ $# -ne 3 ]]; then
echo "Usage: select_option_from_list prompt options[@] result_var"
exit 1
fi

# Assign the arguments to local variables
local prompt="$1"
local options=("${!2}") # Use indirect expansion to get the array from the second argument
local result_var="$3"

# Check if the options array is empty
if [[ ${#options[@]} -eq 0 ]]; then
echo "No options provided. Exiting."
exit 1
fi

# Build an array of whiptail options from the options array
local whiptail_options=()
for ((i=0; i<${#options[@]}; i++)); do
whiptail_options+=("$i" "${options[$i]}")
done

# Use whiptail to display a menu and get the selected index
local selected_index=$(whiptail --title "Select an option" --menu "$prompt" $LINES $COLUMNS $(( $LINES - 8 )) "${whiptail_options[@]}" 3>&1 1>&2 2>&3)

# Check if whiptail exited with a non-zero status or if no option was selected
if [[ $? -ne 0 || -z "$selected_index" ]]; then
echo "No option selected or whiptail error. Exiting."
exit 1
fi

# Get the selected option from the options array using the selected index
local selected_option="${options[$selected_index]}"

# Use indirect assignment to store the selected option in the result variable
eval $result_var="'$selected_option'"
}


function get_text_input() {
if [[ $# -ne 2 ]]; then
echo "Invalid usage. Usage: get_text_input prompt result_var [default_text]"
exit 1
fi

local prompt="$1"
local result_var="$2"
local default_text="$3"

while true; do
local text_input=$(whiptail --title "$prompt" --inputbox "" $LINES $COLUMNS "$default_text" 3>&1 1>&2 2>&3)

if [[ $? -ne 0 ]]; then
echo "No text entered or whiptail error. Exiting."
exit 1
fi

if [[ -z "$text_input" ]]; then
whiptail --title "Error" --msgbox "Text cannot be empty. Please enter some text." $LINES $COLUMNS
else
eval $result_var="'$text_input'"
break
fi
done
}

function remove_backup_tmp() {
# only run if backup-tmp exists
if [ -d backup-tmp ]; then
Expand Down
2 changes: 1 addition & 1 deletion functions/restore_func.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function restore_func() {
archive_path=$(kdialog --getopenfilename /mnt/c 2>/dev/null | tail -n 1 | sed 's/\r$//' || true)
echo "$archive_path"
else
text_input "Please provide the location of the backup archive to restore (drag-n-drop):" archive_path
get_text_input "Please provide the location of the backup archive to restore (drag-n-drop):" archive_path
fi
fi

Expand Down
4 changes: 2 additions & 2 deletions functions/wireless_connection.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ function wireless_connection() {
if (( android_version > 10 )); then
cecho "Running on Android 11 or higher - automatic wireless connections are not supported."
cecho "Please open the settings app on your device, and search for 'Wireless debugging'. Enable the option, press 'Pair device with pairing code', and enter the IP address and port of your device below:"
# Bug: inquirer.sh's text_input doesn't support colons on windows
#text_input "Device IP & Port:" device_ip_port "$device_ip"
# TODO: use get_text_input instead of read
#get_text_input "Device IP & Port:" device_ip_port "$device_ip"
read -p "Pairing IP address & Port: " device_ip_port
cecho "Pairing device..."
adb pair "$device_ip_port"
Expand Down
21 changes: 0 additions & 21 deletions inquirer-sh/LICENSE

This file was deleted.

Loading

0 comments on commit 1818aa4

Please sign in to comment.