summaryrefslogtreecommitdiffstats
path: root/recovery.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'recovery.cpp')
-rw-r--r--recovery.cpp164
1 files changed, 157 insertions, 7 deletions
diff --git a/recovery.cpp b/recovery.cpp
index d803cadf1..de9939357 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -33,7 +33,11 @@
#include "bootloader.h"
#include "common.h"
#include "cutils/properties.h"
+#ifdef ANDROID_RB_RESTART
#include "cutils/android_reboot.h"
+#else
+#include <sys/reboot.h>
+#endif
#include "install.h"
#include "minui/minui.h"
#include "minzip/DirUtil.h"
@@ -46,8 +50,20 @@ extern "C" {
#include "minadbd/adb.h"
}
+extern "C" {
+#include "data.h"
+#include "gui/gui.h"
+}
+#include "partitions.hpp"
+#include "variables.h"
+#include "openrecoveryscript.hpp"
+#include "twrp-functions.hpp"
+
+TWPartitionManager PartitionManager;
+
struct selabel_handle *sehandle;
+
static const struct option OPTIONS[] = {
{ "send_intent", required_argument, NULL, 's' },
{ "update_package", required_argument, NULL, 'u' },
@@ -245,7 +261,7 @@ set_sdcard_update_bootloader_message() {
}
// How much of the temp log we have copied to the copy in cache.
-static long tmplog_offset = 0;
+//static long tmplog_offset = 0;
static void
copy_log_file(const char* source, const char* destination, int append) {
@@ -917,6 +933,10 @@ ui_print(const char* format, ...) {
int
main(int argc, char **argv) {
+ // Recovery needs to install world-readable files, so clear umask
+ // set by init
+ umask(0);
+
time_t start = time(NULL);
// If these fail, there's not really anywhere to complain...
@@ -930,15 +950,40 @@ main(int argc, char **argv) {
// anything in the command file or bootloader control block; the
// only way recovery should be run with this argument is when it
// starts a copy of itself from the apply_from_adb() function.
- if (argc == 2 && strcmp(argv[1], "--adbd") == 0) {
- adb_main();
+ if (argc == 3 && strcmp(argv[1], "--adbd") == 0) {
+ adb_main(argv[2]);
return 0;
}
- printf("Starting recovery on %s", ctime(&start));
+ printf("Starting TWRP %s on %s", TW_VERSION_STR, ctime(&start));
+
+ Device* device = make_device();
+ ui = device->GetUI();
+
+ //ui->Init();
+ //ui->SetBackground(RecoveryUI::NONE);
+ //load_volume_table();
+
+ // Load default values to set DataManager constants and handle ifdefs
+ DataManager_LoadDefaults();
+ printf("Starting the UI...");
+ gui_init();
+ printf("=> Linking mtab\n");
+ symlink("/proc/mounts", "/etc/mtab");
+ printf("=> Processing recovery.fstab\n");
+ if (!PartitionManager.Process_Fstab("/etc/recovery.fstab", 1)) {
+ LOGE("Failing out of recovery due to problem with recovery.fstab.\n");
+ //return -1;
+ }
+ PartitionManager.Output_Partition_Logging();
+ // Load up all the resources
+ gui_loadResources();
+
+ PartitionManager.Mount_By_Path("/cache", true);
load_volume_table();
ensure_path_mounted(LAST_LOG_FILE);
+
rotate_last_logs(10);
get_args(&argc, &argv);
@@ -947,6 +992,7 @@ main(int argc, char **argv) {
const char *update_package = NULL;
int wipe_data = 0, wipe_cache = 0, show_text = 0;
bool just_exit = false;
+ bool perform_backup = false;
int arg;
while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
@@ -989,7 +1035,7 @@ main(int argc, char **argv) {
ui->Print("Warning: No file_contexts\n");
}
- device->StartRecovery();
+ //device->StartRecovery();
printf("Command:");
for (arg = 0; arg < argc; arg++) {
@@ -1017,15 +1063,52 @@ main(int argc, char **argv) {
property_get("ro.build.display.id", recovery_version, "");
printf("\n");
- int status = INSTALL_SUCCESS;
+ // Check for and run startup script if script exists
+ TWFunc::check_and_run_script("/sbin/runatboot.sh", "boot");
+ TWFunc::check_and_run_script("/sbin/postrecoveryboot.sh", "boot");
+
+#ifdef TW_INCLUDE_INJECTTWRP
+ // Back up TWRP Ramdisk if needed:
+ TWPartition* Boot = PartitionManager.Find_Partition_By_Path("/boot");
+ LOGI("Backing up TWRP ramdisk...\n");
+ if (Boot == NULL || Boot->Current_File_System != "emmc")
+ TWFunc::Exec_Cmd("injecttwrp --backup /tmp/backup_recovery_ramdisk.img");
+ else {
+ string injectcmd = "injecttwrp --backup /tmp/backup_recovery_ramdisk.img bd=" + Boot->Actual_Block_Device;
+ TWFunc::Exec_Cmd(injectcmd);
+ }
+ LOGI("Backup of TWRP ramdisk done.\n");
+#endif
+ int status = INSTALL_SUCCESS;
+ string ORSCommand;
+
+ if (perform_backup) {
+ char empt[50];
+ gui_console_only();
+ strcpy(empt, "(Current Date)");
+ DataManager_SetStrValue(TW_BACKUP_NAME, empt);
+ if (!OpenRecoveryScript::Insert_ORS_Command("backup BSDCAE\n"))
+ status = INSTALL_ERROR;
+ }
+ if (status == INSTALL_SUCCESS) { // Prevent other actions if backup failed
if (update_package != NULL) {
+ ORSCommand = "install ";
+ ORSCommand += update_package;
+ ORSCommand += "\n";
+
+ if (OpenRecoveryScript::Insert_ORS_Command(ORSCommand))
+ status = INSTALL_SUCCESS;
+ else
+ status = INSTALL_ERROR;
+ /*
status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE);
if (status == INSTALL_SUCCESS && wipe_cache) {
if (erase_volume("/cache")) {
LOGE("Cache wipe (requested by package) failed.");
}
}
+
if (status != INSTALL_SUCCESS) {
ui->Print("Installation aborted.\n");
@@ -1039,17 +1122,65 @@ main(int argc, char **argv) {
}
}
} else if (wipe_data) {
+ if (!OpenRecoveryScript::Insert_ORS_Command("wipe data\n"))
+ status = INSTALL_ERROR;
+ /*
if (device->WipeData()) status = INSTALL_ERROR;
if (erase_volume("/data")) status = INSTALL_ERROR;
if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
+ */
if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n");
} else if (wipe_cache) {
- if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
+ if (!OpenRecoveryScript::Insert_ORS_Command("wipe cache\n"))
+ status = INSTALL_ERROR;
if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n");
} else if (!just_exit) {
status = INSTALL_NONE; // No command specified
ui->SetBackground(RecoveryUI::NO_COMMAND);
}
+ }
+
+ finish_recovery(NULL);
+ // Offer to decrypt if the device is encrypted
+ if (DataManager_GetIntValue(TW_IS_ENCRYPTED) != 0) {
+ LOGI("Is encrypted, do decrypt page first\n");
+ if (gui_startPage("decrypt") != 0) {
+ LOGE("Failed to start decrypt GUI page.\n");
+ }
+ }
+
+ // Read the settings file
+ DataManager_ReadSettingsFile();
+ // Run any outstanding OpenRecoveryScript
+ if (DataManager_GetIntValue(TW_IS_ENCRYPTED) == 0 && (TWFunc::Path_Exists(SCRIPT_FILE_TMP) || TWFunc::Path_Exists(SCRIPT_FILE_CACHE))) {
+ OpenRecoveryScript::Run_OpenRecoveryScript();
+ }
+ // Launch the main GUI
+ gui_start();
+
+ // Check for su to see if the device is rooted or not
+ if (PartitionManager.Mount_By_Path("/system", false)) {
+ // Disable flashing of stock recovery
+ if (TWFunc::Path_Exists("/system/recovery-from-boot.p")) {
+ rename("/system/recovery-from-boot.p", "/system/recovery-from-boot.bak");
+ ui_print("Renamed stock recovery file in /system to prevent\nthe stock ROM from replacing TWRP.\n");
+ }
+ if (TWFunc::Path_Exists("/supersu/su") && !TWFunc::Path_Exists("/system/bin/su") && !TWFunc::Path_Exists("/system/xbin/su") && !TWFunc::Path_Exists("/system/bin/.ext/.su")) {
+ // Device doesn't have su installed
+ DataManager_SetIntValue("tw_busy", 1);
+ if (gui_startPage("installsu") != 0) {
+ LOGE("Failed to start decrypt GUI page.\n");
+ }
+ } else if (TWFunc::Check_su_Perms() > 0) {
+ // su perms are set incorrectly
+ DataManager_SetIntValue("tw_busy", 1);
+ if (gui_startPage("fixsu") != 0) {
+ LOGE("Failed to start decrypt GUI page.\n");
+ }
+ }
+ sync();
+ PartitionManager.UnMount_By_Path("/system", false);
+ }
if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) {
copy_logs();
@@ -1062,6 +1193,25 @@ main(int argc, char **argv) {
// Otherwise, get ready to boot the main system...
finish_recovery(send_intent);
ui->Print("Rebooting...\n");
+ char backup_arg_char[50];
+ strcpy(backup_arg_char, DataManager_GetStrValue("tw_reboot_arg"));
+ string backup_arg = backup_arg_char;
+ if (backup_arg == "recovery")
+ TWFunc::tw_reboot(rb_recovery);
+ else if (backup_arg == "poweroff")
+ TWFunc::tw_reboot(rb_poweroff);
+ else if (backup_arg == "bootloader")
+ TWFunc::tw_reboot(rb_bootloader);
+ else if (backup_arg == "download")
+ TWFunc::tw_reboot(rb_download);
+ else
+ TWFunc::tw_reboot(rb_system);
+
+#ifdef ANDROID_RB_RESTART
+ android_reboot(ANDROID_RB_RESTART, 0, 0);
+#else
+ reboot(RB_AUTOBOOT);
+#endif
property_set(ANDROID_RB_PROPERTY, "reboot,");
return EXIT_SUCCESS;
}