/* Copyright 2013 bigbiff/Dees_Troy TeamWin This file is part of TWRP/TeamWin Recovery Project. TWRP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. TWRP 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 TWRP. If not, see . */ #include #include #include #include #include #include #include #include "cutils/properties.h" extern "C" { #include "minadbd/adb.h" } #ifdef ANDROID_RB_RESTART #include "cutils/android_reboot.h" #else #include #endif extern "C" { #include "gui/gui.h" } #include "twcommon.h" #include "twrp-functions.hpp" #include "data.hpp" #include "partitions.hpp" #include "openrecoveryscript.hpp" #include "variables.h" TWPartitionManager PartitionManager; int Log_Offset; static void Print_Prop(const char *key, const char *name, void *cookie) { printf("%s=%s\n", key, name); } int main(int argc, char **argv) { // Recovery needs to install world-readable files, so clear umask // set by init umask(0); Log_Offset = 0; // Set up temporary log file (/tmp/recovery.log) freopen(TMP_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TMP_LOG_FILE, "a", stderr); setbuf(stderr, NULL); // Handle ADB sideload if (argc == 3 && strcmp(argv[1], "--adbd") == 0) { adb_main(argv[2]); return 0; } time_t StartupTime = time(NULL); printf("Starting TWRP %s on %s", TW_VERSION_STR, ctime(&StartupTime)); // Load default values to set DataManager constants and handle ifdefs DataManager::SetDefaultValues(); 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)) { LOGERR("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); string Zip_File, Reboot_Value; bool Cache_Wipe = false, Factory_Reset = false, Perform_Backup = false; int index, index2; char* ptr; printf("Startup Commands: "); for (index = 1; index < argc; index++) { printf(" '%s'", argv[index]); if (*argv[index] == 'u') { ptr = argv[index]; index2 = 0; while (*ptr != '=' && *ptr != '\n') ptr++; if (*ptr) { Zip_File = ptr; } else LOGERR("argument error specifying zip file\n"); } else if (*argv[index] == 'c') { Cache_Wipe = true; } else if (*argv[index] == 'w') { Factory_Reset = true; } else if (*argv[index] == 'n') { Perform_Backup = true; } else if (*argv[index] == 's') { ptr = argv[index]; index2 = 0; while (*ptr != '=' && *ptr != '\n') ptr++; if (*ptr) { Reboot_Value = *ptr; } } } char twrp_booted[PROPERTY_VALUE_MAX]; property_get("ro.twrp.boot", twrp_booted, "0"); if (strcmp(twrp_booted, "0") != 0) { property_list(Print_Prop, NULL); printf("\n"); property_set("ro.twrp.boot", "1"); } // 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"); string result; LOGINFO("Backing up TWRP ramdisk...\n"); if (Boot == NULL || Boot->Current_File_System != "emmc") TWFunc::Exec_Cmd("injecttwrp --backup /tmp/backup_recovery_ramdisk.img", result); else { string injectcmd = "injecttwrp --backup /tmp/backup_recovery_ramdisk.img bd=" + Boot->Actual_Block_Device; TWFunc::Exec_Cmd(injectcmd, result); } LOGINFO("Backup of TWRP ramdisk done.\n"); #endif bool Keep_Going = true; if (Perform_Backup) { DataManager::SetValue(TW_BACKUP_NAME, "(Current Date)"); if (!OpenRecoveryScript::Insert_ORS_Command("backup BSDCAE\n")) Keep_Going = false; } if (Keep_Going && !Zip_File.empty()) { string ORSCommand = "install " + Zip_File; if (!OpenRecoveryScript::Insert_ORS_Command(ORSCommand)) Keep_Going = false; } if (Keep_Going) { if (Factory_Reset) { if (!OpenRecoveryScript::Insert_ORS_Command("wipe data\n")) Keep_Going = false; } else if (Cache_Wipe) { if (!OpenRecoveryScript::Insert_ORS_Command("wipe cache\n")) Keep_Going = false; } } TWFunc::Update_Log_File(); // Offer to decrypt if the device is encrypted if (DataManager::GetIntValue(TW_IS_ENCRYPTED) != 0) { LOGINFO("Is encrypted, do decrypt page first\n"); if (gui_startPage("decrypt") != 0) { LOGERR("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"); gui_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::SetValue("tw_busy", 1); if (gui_startPage("installsu") != 0) { LOGERR("Failed to start decrypt GUI page.\n"); } } else if (TWFunc::Check_su_Perms() > 0) { // su perms are set incorrectly DataManager::SetValue("tw_busy", 1); if (gui_startPage("fixsu") != 0) { LOGERR("Failed to start decrypt GUI page.\n"); } } sync(); PartitionManager.UnMount_By_Path("/system", false); } // Reboot TWFunc::Update_Intent_File(Reboot_Value); TWFunc::Update_Log_File(); gui_print("Rebooting...\n"); string Reboot_Arg; DataManager::GetValue("tw_reboot_arg", Reboot_Arg); if (Reboot_Arg == "recovery") TWFunc::tw_reboot(rb_recovery); else if (Reboot_Arg == "poweroff") TWFunc::tw_reboot(rb_poweroff); else if (Reboot_Arg == "bootloader") TWFunc::tw_reboot(rb_bootloader); else if (Reboot_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 return 0; }