blob: 3143863b4f419da02f2284bb34618bf817c6288e [file] [log] [blame]
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -04001/*
2 Copyright 2013 to 2017 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#define __STDC_FORMAT_MACROS 1
20#include <string>
21#include <sys/wait.h>
22#include <sys/stat.h>
23#include <pthread.h>
24#include <zlib.h>
25#include <inttypes.h>
26#include "twrpAdbBuFifo.hpp"
27#include "twcommon.h"
28#include "data.hpp"
29#include "variables.h"
30#include "partitions.hpp"
31#include "twrp-functions.hpp"
32#include "gui/gui.hpp"
33#include "gui/objects.hpp"
34#include "gui/pages.hpp"
35#include "adbbu/twadbstream.h"
36#include "adbbu/libtwadbbu.hpp"
37
38twrpAdbBuFifo::twrpAdbBuFifo(void) {
39 unlink(TW_ADB_FIFO);
40}
41
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -040042void twrpAdbBuFifo::Check_Adb_Fifo_For_Events(void) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040043 char cmd[512];
44
45 memset(&cmd, 0, sizeof(cmd));
46
47 if (read(adb_fifo_fd, &cmd, sizeof(cmd)) > 0) {
48 LOGINFO("adb backup cmd: %s\n", cmd);
49 std::string cmdcheck(cmd);
50 cmdcheck = cmdcheck.substr(0, strlen(ADB_BACKUP_OP));
51 std::string Options(cmd);
52 Options = Options.substr(strlen(ADB_BACKUP_OP) + 1, strlen(cmd));
53 if (cmdcheck == ADB_BACKUP_OP)
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -040054 Backup_ADB_Command(Options);
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040055 else {
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -040056 Restore_ADB_Backup();
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040057 }
58 }
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040059}
60
61bool twrpAdbBuFifo::start(void) {
62 LOGINFO("Starting Adb Backup FIFO\n");
63 unlink(TW_ADB_FIFO);
64 if (mkfifo(TW_ADB_FIFO, 06660) != 0) {
65 LOGINFO("Unable to mkfifo %s\n", TW_ADB_FIFO);
66 return false;
67 }
68 adb_fifo_fd = open(TW_ADB_FIFO, O_RDONLY | O_NONBLOCK);
69 if (adb_fifo_fd < 0) {
70 LOGERR("Unable to open TW_ADB_FIFO for reading.\n");
71 close(adb_fifo_fd);
72 return false;
73 }
74 while (true) {
75 Check_Adb_Fifo_For_Events();
76 usleep(8000);
77 }
78 //Shouldn't get here but cleanup anwyay
79 close(adb_fifo_fd);
80 return true;
81}
82
83pthread_t twrpAdbBuFifo::threadAdbBuFifo(void) {
84 pthread_t thread;
85 ThreadPtr adbfifo = &twrpAdbBuFifo::start;
86 PThreadPtr p = *(PThreadPtr*)&adbfifo;
87 pthread_create(&thread, NULL, p, this);
88 return thread;
89}
90
91bool twrpAdbBuFifo::Backup_ADB_Command(std::string Options) {
92 std::vector<std::string> args;
93 std::string Backup_List;
94 bool adbbackup = true, ret = false;
95 std::string rmopt = "--";
96
97 std::replace(Options.begin(), Options.end(), ':', ' ');
98 args = TWFunc::Split_String(Options, " ");
99
100 DataManager::SetValue(TW_USE_COMPRESSION_VAR, 0);
101 DataManager::SetValue(TW_SKIP_DIGEST_GENERATE_VAR, 0);
102
103 if (args[1].compare("--twrp") != 0) {
104 gui_err("twrp_adbbu_option=--twrp option is required to enable twrp adb backup");
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500105 if (!twadbbu::Write_TWERROR())
106 LOGERR("Unable to write to ADB Backup\n");
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400107 sleep(2);
108 return false;
109 }
110
111 for (unsigned i = 2; i < args.size(); i++) {
112 int compress;
113
114 std::string::size_type size = args[i].find(rmopt);
115 if (size != std::string::npos)
116 args[i].erase(size, rmopt.length());
117
118 if (args[i].compare("compress") == 0) {
119 gui_msg("compression_on=Compression is on");
120 DataManager::SetValue(TW_USE_COMPRESSION_VAR, 1);
121 continue;
122 }
123 DataManager::GetValue(TW_USE_COMPRESSION_VAR, compress);
124 gui_print("%s\n", args[i].c_str());
125 std::string path;
126 path = "/" + args[i];
127 TWPartition* part = PartitionManager.Find_Partition_By_Path(path);
128 if (part) {
129 Backup_List += path;
130 Backup_List += ";";
131 }
132 else {
133 gui_msg(Msg(msg::kError, "partition_not_found=path: {1} not found in partition list")(path));
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500134 if (!twadbbu::Write_TWERROR())
135 LOGERR("Unable to write to TWRP ADB Backup.\n");
136 return false;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400137 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500138}
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400139
140 if (Backup_List.empty()) {
141 DataManager::GetValue("tw_backup_list", Backup_List);
142 if (Backup_List.empty()) {
143 gui_err("no_partition_selected=No partitions selected for backup.");
144 return false;
145 }
146 }
147 else
148 DataManager::SetValue("tw_backup_list", Backup_List);
149
150 DataManager::SetValue("tw_action", "clear");
151 DataManager::SetValue("tw_action_text1", gui_lookup("running_recovery_commands", "Running Recovery Commands"));
152 DataManager::SetValue("tw_action_text2", "");
153 gui_changePage("action_page");
154
155 ret = PartitionManager.Run_Backup(adbbackup);
156 DataManager::SetValue(TW_BACKUP_NAME, gui_lookup("auto_generate", "(Auto Generate)"));
157 if (!ret) {
158 gui_err("backup_fail=Backup failed");
159 return false;
160 }
161 gui_msg("backup_complete=Backup Complete");
162 DataManager::SetValue("ui_progress", 100);
163 sleep(2); //give time for user to see messages on console
164 gui_changePage("main");
165 return true;
166}
167
168bool twrpAdbBuFifo::Restore_ADB_Backup(void) {
169 int partition_count = 0;
170 std::string Restore_Name;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400171 struct AdbBackupFileTrailer adbmd5;
172 struct PartitionSettings part_settings;
Ethan Yonker58f21322018-08-24 11:17:36 -0500173 int adb_control_twrp_fd;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400174 int adb_control_bu_fd, ret = 0;
175 char cmd[512];
176
177 part_settings.total_restore_size = 0;
178
179 PartitionManager.Mount_All_Storage();
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400180 LOGINFO("opening TW_ADB_BU_CONTROL\n");
181 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
182 LOGINFO("opening TW_ADB_TWRP_CONTROL\n");
183 adb_control_twrp_fd = open(TW_ADB_TWRP_CONTROL, O_RDONLY | O_NONBLOCK);
184 memset(&adbmd5, 0, sizeof(adbmd5));
185
186 DataManager::SetValue("tw_action", "clear");
187 DataManager::SetValue("tw_action_text1", gui_lookup("running_recovery_commands", "Running Recovery Commands"));
188 DataManager::SetValue("tw_action_text2", "");
189 gui_changePage("action_page");
190
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500191 while (true) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400192 memset(&cmd, 0, sizeof(cmd));
193 if (read(adb_control_twrp_fd, cmd, sizeof(cmd)) > 0) {
194 struct AdbBackupControlType cmdstruct;
195
196 memset(&cmdstruct, 0, sizeof(cmdstruct));
197 memcpy(&cmdstruct, cmd, sizeof(cmdstruct));
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400198 std::string cmdtype = cmdstruct.get_type();
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400199 if (cmdtype == TWSTREAMHDR) {
200 struct AdbBackupStreamHeader twhdr;
201 memcpy(&twhdr, cmd, sizeof(cmd));
202 LOGINFO("ADB Partition count: %" PRIu64 "\n", twhdr.partition_count);
203 LOGINFO("ADB version: %" PRIu64 "\n", twhdr.version);
204 if (twhdr.version != ADB_BACKUP_VERSION) {
205 LOGERR("Incompatible adb backup version!\n");
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500206 ret = false;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400207 break;
208 }
209 partition_count = twhdr.partition_count;
210 }
211 else if (cmdtype == MD5TRAILER) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500212 LOGINFO("Reading ADB Backup MD5TRAILER\n");
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400213 memcpy(&adbmd5, cmd, sizeof(cmd));
214 }
215 else if (cmdtype == TWMD5) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500216 int check_digest;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400217
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500218 DataManager::GetValue(TW_SKIP_DIGEST_CHECK_VAR, check_digest);
219 if (check_digest > 0) {
220 TWFunc::GUI_Operation_Text(TW_VERIFY_DIGEST_TEXT, gui_parse_text("{@verifying_digest}"));
221 gui_msg("verifying_digest=Verifying Digest");
222 struct AdbBackupFileTrailer md5check;
223 LOGINFO("Verifying md5sums\n");
224
225 memset(&md5check, 0, sizeof(md5check));
226 memcpy(&md5check, cmd, sizeof(cmd));
227 if (strcmp(md5check.md5, adbmd5.md5) != 0) {
228 LOGERR("md5 doesn't match!\n");
229 LOGERR("Stored file md5: %s\n", adbmd5.md5);
230 LOGERR("ADB Backup check md5: %s\n", md5check.md5);
231 ret = false;
232 break;
233 }
234 else {
235 LOGINFO("ADB Backup md5 matches\n");
236 LOGINFO("Stored file md5: %s\n", adbmd5.md5);
237 LOGINFO("ADB Backup check md5: %s\n", md5check.md5);
238 continue;
239 }
240 } else {
241 gui_msg("skip_digest=Skipping Digest check based on user setting.");
242 continue;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400243 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500244
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400245 }
246 else if (cmdtype == TWENDADB) {
247 LOGINFO("received TWENDADB\n");
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500248 ret = 1;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400249 break;
250 }
251 else {
252 struct twfilehdr twimghdr;
253 memcpy(&twimghdr, cmd, sizeof(cmd));
254 std::string cmdstr(twimghdr.type);
255 Restore_Name = twimghdr.name;
256 part_settings.total_restore_size = twimghdr.size;
257 if (cmdtype == TWIMG) {
258 LOGINFO("ADB Type: %s\n", twimghdr.type);
259 LOGINFO("ADB Restore_Name: %s\n", Restore_Name.c_str());
260 LOGINFO("ADB Restore_size: %" PRIu64 "\n", part_settings.total_restore_size);
261 string compression = (twimghdr.compressed == 1) ? "compressed" : "uncompressed";
262 LOGINFO("ADB compression: %s\n", compression.c_str());
263 std::string Backup_FileName;
264 std::size_t pos = Restore_Name.find_last_of("/");
265 std::string path = "/" + Restore_Name.substr(pos, Restore_Name.size());
266 pos = path.find_first_of(".");
267 path = path.substr(0, pos);
268 if (path.substr(0,1).compare("//")) {
269 path = path.substr(1, path.size());
270 }
271
272 pos = Restore_Name.find_last_of("/");
273 Backup_FileName = Restore_Name.substr(pos + 1, Restore_Name.size());
274 part_settings.Part = PartitionManager.Find_Partition_By_Path(path);
275 part_settings.Backup_Folder = path;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400276 part_settings.partition_count = partition_count;
277 part_settings.adbbackup = true;
278 part_settings.adb_compression = twimghdr.compressed;
279 part_settings.PM_Method = PM_RESTORE;
280 ProgressTracking progress(part_settings.total_restore_size);
281 part_settings.progress = &progress;
282 if (!PartitionManager.Restore_Partition(&part_settings)) {
283 LOGERR("ADB Restore failed.\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400284 ret = false;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500285 break;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400286 }
287 }
288 else if (cmdtype == TWFN) {
289 LOGINFO("ADB Type: %s\n", twimghdr.type);
290 LOGINFO("ADB Restore_Name: %s\n", Restore_Name.c_str());
291 LOGINFO("ADB Restore_size: %" PRIi64 "\n", part_settings.total_restore_size);
292 string compression = (twimghdr.compressed == 1) ? "compressed" : "uncompressed";
293 LOGINFO("ADB compression: %s\n", compression.c_str());
294 std::string Backup_FileName;
295 std::size_t pos = Restore_Name.find_last_of("/");
296 std::string path = "/" + Restore_Name.substr(pos, Restore_Name.size());
297 pos = path.find_first_of(".");
298 path = path.substr(0, pos);
299 if (path.substr(0,1).compare("//")) {
300 path = path.substr(1, path.size());
301 }
302
303 pos = Restore_Name.find_last_of("/");
304 Backup_FileName = Restore_Name.substr(pos + 1, Restore_Name.size());
305 pos = Restore_Name.find_last_of("/");
306 part_settings.Part = PartitionManager.Find_Partition_By_Path(path);
307 part_settings.Part->Set_Backup_FileName(Backup_FileName);
308 PartitionManager.Set_Restore_Files(path);
309
Captain Throwback9d6feb52018-07-27 10:05:24 -0400310 if (path.compare(PartitionManager.Get_Android_Root_Path()) == 0) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400311 if (part_settings.Part->Is_Read_Only()) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500312 if (!twadbbu::Write_TWERROR())
313 LOGERR("Unable to write to TWRP ADB Backup.\n");
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400314 gui_msg(Msg(msg::kError, "restore_read_only=Cannot restore {1} -- mounted read only.")(part_settings.Part->Backup_Display_Name));
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500315 ret = false;
316 break;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400317
318 }
319 }
320 part_settings.partition_count = partition_count;
321 part_settings.adbbackup = true;
322 part_settings.adb_compression = twimghdr.compressed;
323 part_settings.total_restore_size += part_settings.Part->Get_Restore_Size(&part_settings);
324 part_settings.PM_Method = PM_RESTORE;
325 ProgressTracking progress(part_settings.total_restore_size);
326 part_settings.progress = &progress;
327 if (!PartitionManager.Restore_Partition(&part_settings)) {
328 LOGERR("ADB Restore failed.\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400329 ret = false;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500330 break;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400331 }
332 }
333 }
334 }
335 }
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400336
337 if (ret != false)
338 gui_msg("restore_complete=Restore Complete");
339 else
340 gui_err("restore_error=Error during restore process.");
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400341
342 if (!twadbbu::Write_TWENDADB())
343 ret = false;
344 sleep(2); //give time for user to see messages on console
345 DataManager::SetValue("ui_progress", 100);
346 gui_changePage("main");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400347 close(adb_control_bu_fd);
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400348 return ret;
349}