From 812660fd1d49bec7129d4c32a8493038a48385d7 Mon Sep 17 00:00:00 2001 From: Dees_Troy Date: Thu, 20 Sep 2012 09:55:17 -0400 Subject: Add and improve OpenRecoveryScript support Improve zip finding in ORS engine Add support for restoring with just a backup name --- Android.mk | 3 +- gui/action.cpp | 6 +- openrecoveryscript.cpp | 476 +++++++++++++++++++++++++++++++++++++++++++++++++ openrecoveryscript.hpp | 42 +++++ partitionmanager.cpp | 9 + partitions.hpp | 1 + recovery.cpp | 14 +- 7 files changed, 546 insertions(+), 5 deletions(-) create mode 100644 openrecoveryscript.cpp create mode 100644 openrecoveryscript.hpp diff --git a/Android.mk b/Android.mk index 600f35635..347af1196 100644 --- a/Android.mk +++ b/Android.mk @@ -36,7 +36,8 @@ LOCAL_SRC_FILES += \ partitionmanager.cpp \ mtdutils/mtdutils.c \ twinstall.cpp \ - twrp-functions.cpp + twrp-functions.cpp \ + openrecoveryscript.cpp ifeq ($(TARGET_RECOVERY_REBOOT_SRC),) LOCAL_SRC_FILES += reboot.c diff --git a/gui/action.cpp b/gui/action.cpp index bbcca23f5..80a582c6c 100644 --- a/gui/action.cpp +++ b/gui/action.cpp @@ -20,6 +20,7 @@ #include #include "../partitions.hpp" #include "../twrp-functions.hpp" +#include "../openrecoveryscript.hpp" #include "../ui.h" #include "../adb_install.h" @@ -1028,10 +1029,9 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) DataManager::SetValue(TW_IS_ENCRYPTED, 0); DataManager::ReadSettingsFile(); -LOGE("TODO: Implement ORS support\n"); - if (0/*check_for_script_file()*/) { + if (OpenRecoveryScript::check_for_script_file()) { ui_print("Processing OpenRecoveryScript file...\n"); - if (/*run_script_file() ==*/ 0) { + if (OpenRecoveryScript::run_script_file() == 0) { usleep(2000000); // Sleep for 2 seconds before rebooting tw_reboot(rb_system); load_theme = 0; diff --git a/openrecoveryscript.cpp b/openrecoveryscript.cpp new file mode 100644 index 000000000..bcd4acb28 --- /dev/null +++ b/openrecoveryscript.cpp @@ -0,0 +1,476 @@ +/* OpenRecoveryScript class for TWRP + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * The code was written from scratch by Dees_Troy dees_troy at + * yahoo + * + * Copyright (c) 2012 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "twrp-functions.hpp" +#include "partitions.hpp" +#include "common.h" +#include "openrecoveryscript.hpp" +#include "variables.h" +extern "C" { +#include "data.h" +#include "twinstall.h" +int TWinstall_zip(const char* path, int* wipe_cache); +} + +static const char *SCRIPT_FILE_CACHE = "/cache/recovery/openrecoveryscript"; +static const char *SCRIPT_FILE_TMP = "/tmp/openrecoveryscript"; +#define SCRIPT_COMMAND_SIZE 512 + +int OpenRecoveryScript::check_for_script_file(void) { + char exec[512]; + + if (!PartitionManager.Mount_By_Path(SCRIPT_FILE_CACHE, false)) { + LOGE("Unable to mount /cache for OpenRecoveryScript support.\n"); + return 0; + } + if (TWFunc::Path_Exists(SCRIPT_FILE_CACHE)) { + LOGI("Script file found: '%s'\n", SCRIPT_FILE_CACHE); + // Copy script file to /tmp + strcpy(exec, "cp "); + strcat(exec, SCRIPT_FILE_CACHE); + strcat(exec, " "); + strcat(exec, SCRIPT_FILE_TMP); + system(exec); + // Delete the file from /cache + strcpy(exec, "rm "); + strcat(exec, SCRIPT_FILE_CACHE); + system(exec); + return 1; + } + return 0; +} + +int OpenRecoveryScript::run_script_file(void) { + FILE *fp = fopen(SCRIPT_FILE_TMP, "r"); + int ret_val = 0, cindex, line_len, i, remove_nl; + char script_line[SCRIPT_COMMAND_SIZE], command[SCRIPT_COMMAND_SIZE], + value[SCRIPT_COMMAND_SIZE], mount[SCRIPT_COMMAND_SIZE], + value1[SCRIPT_COMMAND_SIZE], value2[SCRIPT_COMMAND_SIZE]; + char *val_start, *tok; + + if (fp != NULL) { + while (fgets(script_line, SCRIPT_COMMAND_SIZE, fp) != NULL && ret_val == 0) { + cindex = 0; + line_len = strlen(script_line); + if (line_len < 2) + continue; // there's a blank line or line is too short to contain a command + //ui_print("script line: '%s'\n", script_line); + for (i=0; i 0) { + tw_restore_system = 1; + ui_print("System\n"); + } else if ((value2[i] == 'D' || value2[i] == 'd') && DataManager_GetIntValue(TW_RESTORE_DATA_VAR) > 0) { + tw_restore_data = 1; + ui_print("Data\n"); + } else if ((value2[i] == 'C' || value2[i] == 'c') && DataManager_GetIntValue(TW_RESTORE_CACHE_VAR) > 0) { + tw_restore_cache = 1; + ui_print("Cache\n"); + } else if ((value2[i] == 'R' || value2[i] == 'r') && DataManager_GetIntValue(TW_RESTORE_RECOVERY_VAR) > 0) { + tw_restore_recovery = 1; + ui_print("Recovery\n"); + } else if (value2[i] == '1' && DataManager_GetIntValue(TW_RESTORE_SP1_VAR) > 0) { + tw_restore_sp1 = 1; + ui_print("%s\n", "Special1"); + } else if (value2[i] == '2' && DataManager_GetIntValue(TW_RESTORE_SP2_VAR) > 0) { + tw_restore_sp2 = 1; + ui_print("%s\n", "Special2"); + } else if (value2[i] == '3' && DataManager_GetIntValue(TW_RESTORE_SP3_VAR) > 0) { + tw_restore_sp3 = 1; + ui_print("%s\n", "Special3"); + } else if ((value2[i] == 'B' || value2[i] == 'b') && DataManager_GetIntValue(TW_RESTORE_BOOT_VAR) > 0) { + tw_restore_boot = 1; + ui_print("Boot\n"); + } else if ((value2[i] == 'A' || value2[i] == 'a') && DataManager_GetIntValue(TW_RESTORE_ANDSEC_VAR) > 0) { + tw_restore_andsec = 1; + ui_print("Android Secure\n"); + } else if ((value2[i] == 'E' || value2[i] == 'e') && DataManager_GetIntValue(TW_RESTORE_SDEXT_VAR) > 0) { + tw_restore_sdext = 1; + ui_print("SD-Ext\n"); + } else if (value2[i] == 'M' || value2[i] == 'm') { + DataManager_SetIntValue(TW_SKIP_MD5_CHECK_VAR, 1); + ui_print("MD5 check skip is on\n"); + } + } + + if (DataManager_GetIntValue(TW_RESTORE_SYSTEM_VAR) && !tw_restore_system) + DataManager_SetIntValue(TW_RESTORE_SYSTEM_VAR, 0); + if (DataManager_GetIntValue(TW_RESTORE_DATA_VAR) && !tw_restore_data) + DataManager_SetIntValue(TW_RESTORE_DATA_VAR, 0); + if (DataManager_GetIntValue(TW_RESTORE_CACHE_VAR) && !tw_restore_cache) + DataManager_SetIntValue(TW_RESTORE_CACHE_VAR, 0); + if (DataManager_GetIntValue(TW_RESTORE_RECOVERY_VAR) && !tw_restore_recovery) + DataManager_SetIntValue(TW_RESTORE_RECOVERY_VAR, 0); + if (DataManager_GetIntValue(TW_RESTORE_BOOT_VAR) && !tw_restore_boot) + DataManager_SetIntValue(TW_RESTORE_BOOT_VAR, 0); + if (DataManager_GetIntValue(TW_RESTORE_ANDSEC_VAR) && !tw_restore_andsec) + DataManager_SetIntValue(TW_RESTORE_ANDSEC_VAR, 0); + if (DataManager_GetIntValue(TW_RESTORE_SDEXT_VAR) && !tw_restore_sdext) + DataManager_SetIntValue(TW_RESTORE_SDEXT_VAR, 0); + if (DataManager_GetIntValue(TW_RESTORE_SP1_VAR) && !tw_restore_sp1) + DataManager_SetIntValue(TW_RESTORE_SP1_VAR, 0); + if (DataManager_GetIntValue(TW_RESTORE_SP2_VAR) && !tw_restore_sp2) + DataManager_SetIntValue(TW_RESTORE_SP2_VAR, 0); + if (DataManager_GetIntValue(TW_RESTORE_SP3_VAR) && !tw_restore_sp3) + DataManager_SetIntValue(TW_RESTORE_SP3_VAR, 0); + } else { + ui_print("No restore options set.\n"); + ret_val = 1; + continue; + } + PartitionManager.Run_Restore(folder_path); + ui_print("Restore complete!\n"); + } else if (strcmp(command, "mount") == 0) { + // Mount + if (value[0] != '/') { + strcpy(mount, "/"); + strcat(mount, value); + } else + strcpy(mount, value); + if (PartitionManager.Mount_By_Path(mount, true)) + ui_print("Mounted '%s'\n", mount); + } else if (strcmp(command, "unmount") == 0 || strcmp(command, "umount") == 0) { + // Unmount + if (value[0] != '/') { + strcpy(mount, "/"); + strcat(mount, value); + } else + strcpy(mount, value); + if (PartitionManager.UnMount_By_Path(mount, true)) + ui_print("Unmounted '%s'\n", mount); + } else if (strcmp(command, "set") == 0) { + // Set value + tok = strtok(value, " "); + strcpy(value1, tok); + tok = strtok(NULL, " "); + strcpy(value2, tok); + ui_print("Setting '%s' to '%s'\n", value1, value2); + DataManager_SetStrValue(value1, value2); + } else if (strcmp(command, "mkdir") == 0) { + // Make directory (recursive) + ui_print("Making directory (recursive): '%s'\n", value); + if (TWFunc::Recursive_Mkdir(value)) { + LOGE("Unable to create folder: '%s'\n", value); + ret_val = 1; + } + } else if (strcmp(command, "reboot") == 0) { + // Reboot + } else if (strcmp(command, "cmd") == 0) { + if (cindex != 0) { + system(value); + } else { + LOGE("No value given for cmd\n"); + } + } else if (strcmp(command, "print") == 0) { + ui_print("%s\n", value); + } else { + LOGE("Unrecognized script command: '%s'\n", command); + ret_val = 1; + } + } + fclose(fp); + ui_print("Done processing script file\n"); + } else { + LOGE("Error opening script file '%s'\n", SCRIPT_FILE_TMP); + return 1; + } + return ret_val; +} + +string OpenRecoveryScript::Locate_Zip_File(string Zip, string Storage_Root) { + string Path = TWFunc::Get_Path(Zip); + string File = TWFunc::Get_Filename(Zip); + string pathCpy = Path; + string wholePath; + size_t pos = Path.find("/", 1); + + while (pos != string::npos) + { + pathCpy = Path.substr(pos, Path.size() - pos); + wholePath = pathCpy + "/" + File; + if (TWFunc::Path_Exists(wholePath)) + return wholePath; + wholePath = Storage_Root + "/" + wholePath; + if (TWFunc::Path_Exists(wholePath)) + return wholePath; + + pos = Path.find("/", pos + 1); + } + return ""; +} \ No newline at end of file diff --git a/openrecoveryscript.hpp b/openrecoveryscript.hpp new file mode 100644 index 000000000..6b210548b --- /dev/null +++ b/openrecoveryscript.hpp @@ -0,0 +1,42 @@ +/* OpenRecoveryScript class for TWRP + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * The code was written from scratch by Dees_Troy dees_troy at + * yahoo + * + * Copyright (c) 2012 + */ + +#ifndef _OPENRECOVERYSCRIPT_HPP +#define _OPENRECOVERYSCRIPT_HPP + +#include + +using namespace std; + +// Partition class +class OpenRecoveryScript +{ +public: + static int check_for_script_file(); // Checks to see if the ORS file is present in /cache + static int run_script_file(); // Executes the commands in the ORS file + +private: + static string Locate_Zip_File(string Path, string File); // Attempts to locate the zip file in storage + +}; + +#endif // _OPENRECOVERYSCRIPT_HPP diff --git a/partitionmanager.cpp b/partitionmanager.cpp index b2bbf8e8e..67ec84ec5 100644 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -1497,4 +1497,13 @@ int TWPartitionManager::usb_storage_disable(void) { Mount_By_Path(DataManager::GetSettingsStoragePath(), true); Mount_By_Path(DataManager::GetCurrentStoragePath(), true); return true; +} + +void TWPartitionManager::Mount_All_Storage(void) { + std::vector::iterator iter; + + for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { + if ((*iter)->Is_Storage) + (*iter)->Mount(false); + } } \ No newline at end of file diff --git a/partitions.hpp b/partitions.hpp index 32c4f453a..c253d3b83 100644 --- a/partitions.hpp +++ b/partitions.hpp @@ -173,6 +173,7 @@ public: virtual int Fix_Permissions(); // Fixes permissions in /system and /data virtual int usb_storage_enable(void); // Enable USB storage mode virtual int usb_storage_disable(void); // Disable USB storage mode + virtual void Mount_All_Storage(void); // Mounts all storage locations private: bool Make_MD5(bool generate_md5, string Backup_Folder, string Backup_Filename); // Generates an MD5 after a backup is made diff --git a/recovery.cpp b/recovery.cpp index 2d89014c1..8cf31069e 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -56,6 +56,7 @@ extern "C" { } #include "partitions.hpp" #include "variables.h" +#include "openrecoveryscript.hpp" TWPartitionManager PartitionManager; @@ -924,8 +925,19 @@ main(int argc, char **argv) { //if (status != INSTALL_SUCCESS) ui->SetBackground(RecoveryUI::ERROR); if (status != INSTALL_SUCCESS /*|| ui->IsTextVisible()*/) { + finish_recovery(NULL); DataManager_ReadSettingsFile(); - gui_start(); + if (DataManager_GetIntValue(TW_IS_ENCRYPTED) == 0 && OpenRecoveryScript::check_for_script_file()) { + gui_console_only(); + OpenRecoveryScript::run_script_file(); + if (1 || OpenRecoveryScript::run_script_file() != 0) { + // There was an error, boot the recovery + gui_start(); + } else { + usleep(2000000); // Sleep for 2 seconds before rebooting + } + } else + gui_start(); //prompt_and_wait(device); } -- cgit v1.2.3