blob: 0c7dd152476979b90ed0257d54c4ef13b07802bb [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];
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -040044 int ret;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040045
46 memset(&cmd, 0, sizeof(cmd));
47
48 if (read(adb_fifo_fd, &cmd, sizeof(cmd)) > 0) {
49 LOGINFO("adb backup cmd: %s\n", cmd);
50 std::string cmdcheck(cmd);
51 cmdcheck = cmdcheck.substr(0, strlen(ADB_BACKUP_OP));
52 std::string Options(cmd);
53 Options = Options.substr(strlen(ADB_BACKUP_OP) + 1, strlen(cmd));
54 if (cmdcheck == ADB_BACKUP_OP)
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -040055 Backup_ADB_Command(Options);
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040056 else {
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -040057 Restore_ADB_Backup();
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040058 }
59 }
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040060}
61
62bool twrpAdbBuFifo::start(void) {
63 LOGINFO("Starting Adb Backup FIFO\n");
64 unlink(TW_ADB_FIFO);
65 if (mkfifo(TW_ADB_FIFO, 06660) != 0) {
66 LOGINFO("Unable to mkfifo %s\n", TW_ADB_FIFO);
67 return false;
68 }
69 adb_fifo_fd = open(TW_ADB_FIFO, O_RDONLY | O_NONBLOCK);
70 if (adb_fifo_fd < 0) {
71 LOGERR("Unable to open TW_ADB_FIFO for reading.\n");
72 close(adb_fifo_fd);
73 return false;
74 }
75 while (true) {
76 Check_Adb_Fifo_For_Events();
77 usleep(8000);
78 }
79 //Shouldn't get here but cleanup anwyay
80 close(adb_fifo_fd);
81 return true;
82}
83
84pthread_t twrpAdbBuFifo::threadAdbBuFifo(void) {
85 pthread_t thread;
86 ThreadPtr adbfifo = &twrpAdbBuFifo::start;
87 PThreadPtr p = *(PThreadPtr*)&adbfifo;
88 pthread_create(&thread, NULL, p, this);
89 return thread;
90}
91
92bool twrpAdbBuFifo::Backup_ADB_Command(std::string Options) {
93 std::vector<std::string> args;
94 std::string Backup_List;
95 bool adbbackup = true, ret = false;
96 std::string rmopt = "--";
97
98 std::replace(Options.begin(), Options.end(), ':', ' ');
99 args = TWFunc::Split_String(Options, " ");
100
101 DataManager::SetValue(TW_USE_COMPRESSION_VAR, 0);
102 DataManager::SetValue(TW_SKIP_DIGEST_GENERATE_VAR, 0);
103
104 if (args[1].compare("--twrp") != 0) {
105 gui_err("twrp_adbbu_option=--twrp option is required to enable twrp adb backup");
106 sleep(2);
107 return false;
108 }
109
110 for (unsigned i = 2; i < args.size(); i++) {
111 int compress;
112
113 std::string::size_type size = args[i].find(rmopt);
114 if (size != std::string::npos)
115 args[i].erase(size, rmopt.length());
116
117 if (args[i].compare("compress") == 0) {
118 gui_msg("compression_on=Compression is on");
119 DataManager::SetValue(TW_USE_COMPRESSION_VAR, 1);
120 continue;
121 }
122 DataManager::GetValue(TW_USE_COMPRESSION_VAR, compress);
123 gui_print("%s\n", args[i].c_str());
124 std::string path;
125 path = "/" + args[i];
126 TWPartition* part = PartitionManager.Find_Partition_By_Path(path);
127 if (part) {
128 Backup_List += path;
129 Backup_List += ";";
130 }
131 else {
132 gui_msg(Msg(msg::kError, "partition_not_found=path: {1} not found in partition list")(path));
133 return false;
134 }
135 }
136
137 if (Backup_List.empty()) {
138 DataManager::GetValue("tw_backup_list", Backup_List);
139 if (Backup_List.empty()) {
140 gui_err("no_partition_selected=No partitions selected for backup.");
141 return false;
142 }
143 }
144 else
145 DataManager::SetValue("tw_backup_list", Backup_List);
146
147 DataManager::SetValue("tw_action", "clear");
148 DataManager::SetValue("tw_action_text1", gui_lookup("running_recovery_commands", "Running Recovery Commands"));
149 DataManager::SetValue("tw_action_text2", "");
150 gui_changePage("action_page");
151
152 ret = PartitionManager.Run_Backup(adbbackup);
153 DataManager::SetValue(TW_BACKUP_NAME, gui_lookup("auto_generate", "(Auto Generate)"));
154 if (!ret) {
155 gui_err("backup_fail=Backup failed");
156 return false;
157 }
158 gui_msg("backup_complete=Backup Complete");
159 DataManager::SetValue("ui_progress", 100);
160 sleep(2); //give time for user to see messages on console
161 gui_changePage("main");
162 return true;
163}
164
165bool twrpAdbBuFifo::Restore_ADB_Backup(void) {
166 int partition_count = 0;
167 std::string Restore_Name;
168 std::size_t pos = 0;
169 struct AdbBackupFileTrailer adbmd5;
170 struct PartitionSettings part_settings;
171 int adb_control_twrp_fd, adb_write_fd, systemro;
172 int adb_control_bu_fd, ret = 0;
173 char cmd[512];
174
175 part_settings.total_restore_size = 0;
176
177 PartitionManager.Mount_All_Storage();
178 DataManager::SetValue(TW_SKIP_DIGEST_CHECK_VAR, 0);
179 LOGINFO("opening TW_ADB_BU_CONTROL\n");
180 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
181 LOGINFO("opening TW_ADB_TWRP_CONTROL\n");
182 adb_control_twrp_fd = open(TW_ADB_TWRP_CONTROL, O_RDONLY | O_NONBLOCK);
183 memset(&adbmd5, 0, sizeof(adbmd5));
184
185 DataManager::SetValue("tw_action", "clear");
186 DataManager::SetValue("tw_action_text1", gui_lookup("running_recovery_commands", "Running Recovery Commands"));
187 DataManager::SetValue("tw_action_text2", "");
188 gui_changePage("action_page");
189
190 while (1) {
191 memset(&cmd, 0, sizeof(cmd));
192 if (read(adb_control_twrp_fd, cmd, sizeof(cmd)) > 0) {
193 struct AdbBackupControlType cmdstruct;
194
195 memset(&cmdstruct, 0, sizeof(cmdstruct));
196 memcpy(&cmdstruct, cmd, sizeof(cmdstruct));
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400197 std::string cmdtype = cmdstruct.get_type();
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400198 if (cmdtype == TWSTREAMHDR) {
199 struct AdbBackupStreamHeader twhdr;
200 memcpy(&twhdr, cmd, sizeof(cmd));
201 LOGINFO("ADB Partition count: %" PRIu64 "\n", twhdr.partition_count);
202 LOGINFO("ADB version: %" PRIu64 "\n", twhdr.version);
203 if (twhdr.version != ADB_BACKUP_VERSION) {
204 LOGERR("Incompatible adb backup version!\n");
205 break;
206 }
207 partition_count = twhdr.partition_count;
208 }
209 else if (cmdtype == MD5TRAILER) {
210 LOGINFO("Restoring MD5TRAILER\n");
211 memcpy(&adbmd5, cmd, sizeof(cmd));
212 }
213 else if (cmdtype == TWMD5) {
214 struct AdbBackupFileTrailer md5check;
215 LOGINFO("Restoring TWMD5\n");
216
217 memset(&md5check, 0, sizeof(md5check));
218 memcpy(&md5check, cmd, sizeof(cmd));
219 if (strcmp(md5check.md5, adbmd5.md5) != 0) {
220 LOGERR("md5 doesn't match!\n");
221 LOGERR("file md5: %s\n", adbmd5.md5);
222 LOGERR("check md5: %s\n", md5check.md5);
223 ret = false;
224 break;
225 }
226 else {
227 LOGINFO("adbrestore md5 matches\n");
228 LOGINFO("adbmd5.md5: %s\n", adbmd5.md5);
229 LOGINFO("md5check.md5: %s\n", md5check.md5);
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400230 ret = true;
231 break;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400232 }
233 }
234 else if (cmdtype == TWENDADB) {
235 LOGINFO("received TWENDADB\n");
236 break;
237 }
238 else {
239 struct twfilehdr twimghdr;
240 memcpy(&twimghdr, cmd, sizeof(cmd));
241 std::string cmdstr(twimghdr.type);
242 Restore_Name = twimghdr.name;
243 part_settings.total_restore_size = twimghdr.size;
244 if (cmdtype == TWIMG) {
245 LOGINFO("ADB Type: %s\n", twimghdr.type);
246 LOGINFO("ADB Restore_Name: %s\n", Restore_Name.c_str());
247 LOGINFO("ADB Restore_size: %" PRIu64 "\n", part_settings.total_restore_size);
248 string compression = (twimghdr.compressed == 1) ? "compressed" : "uncompressed";
249 LOGINFO("ADB compression: %s\n", compression.c_str());
250 std::string Backup_FileName;
251 std::size_t pos = Restore_Name.find_last_of("/");
252 std::string path = "/" + Restore_Name.substr(pos, Restore_Name.size());
253 pos = path.find_first_of(".");
254 path = path.substr(0, pos);
255 if (path.substr(0,1).compare("//")) {
256 path = path.substr(1, path.size());
257 }
258
259 pos = Restore_Name.find_last_of("/");
260 Backup_FileName = Restore_Name.substr(pos + 1, Restore_Name.size());
261 part_settings.Part = PartitionManager.Find_Partition_By_Path(path);
262 part_settings.Backup_Folder = path;
263 PartitionManager.Set_Restore_Files(path);
264 part_settings.partition_count = partition_count;
265 part_settings.adbbackup = true;
266 part_settings.adb_compression = twimghdr.compressed;
267 part_settings.PM_Method = PM_RESTORE;
268 ProgressTracking progress(part_settings.total_restore_size);
269 part_settings.progress = &progress;
270 if (!PartitionManager.Restore_Partition(&part_settings)) {
271 LOGERR("ADB Restore failed.\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400272 ret = false;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400273 }
274 }
275 else if (cmdtype == TWFN) {
276 LOGINFO("ADB Type: %s\n", twimghdr.type);
277 LOGINFO("ADB Restore_Name: %s\n", Restore_Name.c_str());
278 LOGINFO("ADB Restore_size: %" PRIi64 "\n", part_settings.total_restore_size);
279 string compression = (twimghdr.compressed == 1) ? "compressed" : "uncompressed";
280 LOGINFO("ADB compression: %s\n", compression.c_str());
281 std::string Backup_FileName;
282 std::size_t pos = Restore_Name.find_last_of("/");
283 std::string path = "/" + Restore_Name.substr(pos, Restore_Name.size());
284 pos = path.find_first_of(".");
285 path = path.substr(0, pos);
286 if (path.substr(0,1).compare("//")) {
287 path = path.substr(1, path.size());
288 }
289
290 pos = Restore_Name.find_last_of("/");
291 Backup_FileName = Restore_Name.substr(pos + 1, Restore_Name.size());
292 pos = Restore_Name.find_last_of("/");
293 part_settings.Part = PartitionManager.Find_Partition_By_Path(path);
294 part_settings.Part->Set_Backup_FileName(Backup_FileName);
295 PartitionManager.Set_Restore_Files(path);
296
297 if (path.compare("/system") == 0) {
298 if (part_settings.Part->Is_Read_Only()) {
299 struct AdbBackupControlType twerror;
300 strncpy(twerror.start_of_header, TWRP, sizeof(twerror.start_of_header));
301 strncpy(twerror.type, TWERROR, sizeof(twerror.type));
302 memset(twerror.space, 0, sizeof(twerror.space));
303 twerror.crc = crc32(0L, Z_NULL, 0);
304 twerror.crc = crc32(twerror.crc, (const unsigned char*) &twerror, sizeof(twerror));
305 if (write(adb_control_bu_fd, &twerror, sizeof(twerror)) < 0) {
306 LOGERR("Cannot write to ADB_CONTROL_BU_FD: %s\n", strerror(errno));
307 }
308 gui_msg(Msg(msg::kError, "restore_read_only=Cannot restore {1} -- mounted read only.")(part_settings.Part->Backup_Display_Name));
309 return false;
310
311 }
312 }
313 part_settings.partition_count = partition_count;
314 part_settings.adbbackup = true;
315 part_settings.adb_compression = twimghdr.compressed;
316 part_settings.total_restore_size += part_settings.Part->Get_Restore_Size(&part_settings);
317 part_settings.PM_Method = PM_RESTORE;
318 ProgressTracking progress(part_settings.total_restore_size);
319 part_settings.progress = &progress;
320 if (!PartitionManager.Restore_Partition(&part_settings)) {
321 LOGERR("ADB Restore failed.\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400322 ret = false;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400323 }
324 }
325 }
326 }
327 }
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400328
329 if (ret != false)
330 gui_msg("restore_complete=Restore Complete");
331 else
332 gui_err("restore_error=Error during restore process.");
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400333
334 if (!twadbbu::Write_TWENDADB())
335 ret = false;
336 sleep(2); //give time for user to see messages on console
337 DataManager::SetValue("ui_progress", 100);
338 gui_changePage("main");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400339 close(adb_control_bu_fd);
340 close(adb_control_twrp_fd);
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400341 return ret;
342}