blob: 938a07adf8db3ff34878cff04c55a9a723d92e8d [file] [log] [blame]
Dees_Troy2673cec2013-04-02 20:22:16 +00001/*
2 Copyright 2013 bigbiff/Dees_Troy TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <sys/stat.h>
23#include <sys/types.h>
24#include <time.h>
25#include <unistd.h>
26
27#include "cutils/properties.h"
28extern "C" {
29#include "minadbd/adb.h"
30}
31
32#ifdef ANDROID_RB_RESTART
33#include "cutils/android_reboot.h"
34#else
35#include <sys/reboot.h>
36#endif
37
38extern "C" {
39#include "gui/gui.h"
40}
41#include "twcommon.h"
42#include "twrp-functions.hpp"
43#include "data.hpp"
44#include "partitions.hpp"
45#include "openrecoveryscript.hpp"
46#include "variables.h"
47
48TWPartitionManager PartitionManager;
49int Log_Offset;
50
51static void Print_Prop(const char *key, const char *name, void *cookie) {
52 printf("%s=%s\n", key, name);
53}
54
55int main(int argc, char **argv) {
56 // Recovery needs to install world-readable files, so clear umask
57 // set by init
58 umask(0);
59
60 Log_Offset = 0;
61
62 // Set up temporary log file (/tmp/recovery.log)
63 freopen(TMP_LOG_FILE, "a", stdout);
64 setbuf(stdout, NULL);
65 freopen(TMP_LOG_FILE, "a", stderr);
66 setbuf(stderr, NULL);
67
68 // Handle ADB sideload
69 if (argc == 3 && strcmp(argv[1], "--adbd") == 0) {
70 adb_main(argv[2]);
71 return 0;
72 }
73
74 time_t StartupTime = time(NULL);
75 printf("Starting TWRP %s on %s", TW_VERSION_STR, ctime(&StartupTime));
76
77 // Load default values to set DataManager constants and handle ifdefs
78 DataManager::SetDefaultValues();
79 printf("Starting the UI...");
80 gui_init();
81 printf("=> Linking mtab\n");
82 symlink("/proc/mounts", "/etc/mtab");
83 printf("=> Processing recovery.fstab\n");
84 if (!PartitionManager.Process_Fstab("/etc/recovery.fstab", 1)) {
85 LOGERR("Failing out of recovery due to problem with recovery.fstab.\n");
86 return -1;
87 }
88 PartitionManager.Output_Partition_Logging();
89 // Load up all the resources
90 gui_loadResources();
91
92 PartitionManager.Mount_By_Path("/cache", true);
93
94 string Zip_File, Reboot_Value;
95 bool Cache_Wipe = false, Factory_Reset = false, Perform_Backup = false;
96
97 int index, index2;
98 char* ptr;
99 printf("Startup Commands: ");
100 for (index = 1; index < argc; index++) {
101 printf(" '%s'", argv[index]);
102 if (*argv[index] == 'u') {
103 ptr = argv[index];
104 index2 = 0;
105 while (*ptr != '=' && *ptr != '\n')
106 ptr++;
107 if (*ptr) {
108 Zip_File = ptr;
109 } else
110 LOGERR("argument error specifying zip file\n");
111 } else if (*argv[index] == 'c') {
112 Cache_Wipe = true;
113 } else if (*argv[index] == 'w') {
114 Factory_Reset = true;
115 } else if (*argv[index] == 'n') {
116 Perform_Backup = true;
117 } else if (*argv[index] == 's') {
118 ptr = argv[index];
119 index2 = 0;
120 while (*ptr != '=' && *ptr != '\n')
121 ptr++;
122 if (*ptr) {
123 Reboot_Value = *ptr;
124 }
125 }
126 }
127
128 char twrp_booted[PROPERTY_VALUE_MAX];
129 property_get("ro.twrp.boot", twrp_booted, "0");
130 if (strcmp(twrp_booted, "0") != 0) {
131 property_list(Print_Prop, NULL);
132 printf("\n");
133 property_set("ro.twrp.boot", "1");
134 }
135
136 // Check for and run startup script if script exists
137 TWFunc::check_and_run_script("/sbin/runatboot.sh", "boot");
138 TWFunc::check_and_run_script("/sbin/postrecoveryboot.sh", "boot");
139
140#ifdef TW_INCLUDE_INJECTTWRP
141 // Back up TWRP Ramdisk if needed:
142 TWPartition* Boot = PartitionManager.Find_Partition_By_Path("/boot");
143 string result;
144 LOGINFO("Backing up TWRP ramdisk...\n");
145 if (Boot == NULL || Boot->Current_File_System != "emmc")
146 TWFunc::Exec_Cmd("injecttwrp --backup /tmp/backup_recovery_ramdisk.img", result);
147 else {
148 string injectcmd = "injecttwrp --backup /tmp/backup_recovery_ramdisk.img bd=" + Boot->Actual_Block_Device;
149 TWFunc::Exec_Cmd(injectcmd, result);
150 }
151 LOGINFO("Backup of TWRP ramdisk done.\n");
152#endif
153
154 bool Keep_Going = true;
155 if (Perform_Backup) {
156 DataManager::SetValue(TW_BACKUP_NAME, "(Current Date)");
157 if (!OpenRecoveryScript::Insert_ORS_Command("backup BSDCAE\n"))
158 Keep_Going = false;
159 }
160 if (Keep_Going && !Zip_File.empty()) {
161 string ORSCommand = "install " + Zip_File;
162
163 if (!OpenRecoveryScript::Insert_ORS_Command(ORSCommand))
164 Keep_Going = false;
165 }
166 if (Keep_Going) {
167 if (Factory_Reset) {
168 if (!OpenRecoveryScript::Insert_ORS_Command("wipe data\n"))
169 Keep_Going = false;
170 } else if (Cache_Wipe) {
171 if (!OpenRecoveryScript::Insert_ORS_Command("wipe cache\n"))
172 Keep_Going = false;
173 }
174 }
175
176 TWFunc::Update_Log_File();
177 // Offer to decrypt if the device is encrypted
178 if (DataManager::GetIntValue(TW_IS_ENCRYPTED) != 0) {
179 LOGINFO("Is encrypted, do decrypt page first\n");
180 if (gui_startPage("decrypt") != 0) {
181 LOGERR("Failed to start decrypt GUI page.\n");
182 }
183 }
184
185 // Read the settings file
186 DataManager::ReadSettingsFile();
187 // Run any outstanding OpenRecoveryScript
188 if (DataManager::GetIntValue(TW_IS_ENCRYPTED) == 0 && (TWFunc::Path_Exists(SCRIPT_FILE_TMP) || TWFunc::Path_Exists(SCRIPT_FILE_CACHE))) {
189 OpenRecoveryScript::Run_OpenRecoveryScript();
190 }
191 // Launch the main GUI
192 gui_start();
193
194 // Check for su to see if the device is rooted or not
195 if (PartitionManager.Mount_By_Path("/system", false)) {
196 // Disable flashing of stock recovery
197 if (TWFunc::Path_Exists("/system/recovery-from-boot.p")) {
198 rename("/system/recovery-from-boot.p", "/system/recovery-from-boot.bak");
199 gui_print("Renamed stock recovery file in /system to prevent\nthe stock ROM from replacing TWRP.\n");
200 }
201 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")) {
202 // Device doesn't have su installed
203 DataManager::SetValue("tw_busy", 1);
204 if (gui_startPage("installsu") != 0) {
205 LOGERR("Failed to start decrypt GUI page.\n");
206 }
207 } else if (TWFunc::Check_su_Perms() > 0) {
208 // su perms are set incorrectly
209 DataManager::SetValue("tw_busy", 1);
210 if (gui_startPage("fixsu") != 0) {
211 LOGERR("Failed to start decrypt GUI page.\n");
212 }
213 }
214 sync();
215 PartitionManager.UnMount_By_Path("/system", false);
216 }
217
218 // Reboot
219 TWFunc::Update_Intent_File(Reboot_Value);
220 TWFunc::Update_Log_File();
221 gui_print("Rebooting...\n");
222 string Reboot_Arg;
223 DataManager::GetValue("tw_reboot_arg", Reboot_Arg);
224 if (Reboot_Arg == "recovery")
225 TWFunc::tw_reboot(rb_recovery);
226 else if (Reboot_Arg == "poweroff")
227 TWFunc::tw_reboot(rb_poweroff);
228 else if (Reboot_Arg == "bootloader")
229 TWFunc::tw_reboot(rb_bootloader);
230 else if (Reboot_Arg == "download")
231 TWFunc::tw_reboot(rb_download);
232 else
233 TWFunc::tw_reboot(rb_system);
234
235#ifdef ANDROID_RB_RESTART
236 android_reboot(ANDROID_RB_RESTART, 0, 0);
237#else
238 reboot(RB_AUTOBOOT);
239#endif
240 return 0;
241}