blob: b3de76db69dcaa940abe878d59719c616b9e7ec6 [file] [log] [blame]
bigbiffce8f83c2015-12-12 18:30:21 -05001/*
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -04002 Copyright 2013 to 2017 TeamWin
bigbiffce8f83c2015-12-12 18:30:21 -05003 TWRP is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 TWRP is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <unistd.h>
bigbiffce8f83c2015-12-12 18:30:21 -050021#include <fcntl.h>
22#include <errno.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <sys/select.h>
26#include <sys/time.h>
27#include <zlib.h>
28#include <ctype.h>
29#include <semaphore.h>
30#include <string>
bigbiffce8f83c2015-12-12 18:30:21 -050031#include <sstream>
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040032#include <fstream>
bigbiffce8f83c2015-12-12 18:30:21 -050033#include <algorithm>
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040034#include <utils/threads.h>
35#include <pthread.h>
bigbiffce8f83c2015-12-12 18:30:21 -050036
37#include "twadbstream.h"
38#include "twrpback.hpp"
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -040039#include "libtwadbbu.hpp"
bigbiff bigbiff56cf5642016-08-19 17:43:45 -040040#include "../twrpDigest/twrpDigest.hpp"
41#include "../twrpDigest/twrpMD5.hpp"
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040042#include "../twrpAdbBuFifo.hpp"
bigbiffce8f83c2015-12-12 18:30:21 -050043
44twrpback::twrpback(void) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -050045 adbd_fp = NULL;
bigbiffce8f83c2015-12-12 18:30:21 -050046 read_fd = 0;
47 write_fd = 0;
48 adb_control_twrp_fd = 0;
49 adb_control_bu_fd = 0;
50 adb_read_fd = 0;
51 adb_write_fd = 0;
bigbiffce8f83c2015-12-12 18:30:21 -050052 ors_fd = 0;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -050053 debug_adb_fd = 0;
bigbiffce8f83c2015-12-12 18:30:21 -050054 firstPart = true;
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040055 createFifos();
bigbiffce8f83c2015-12-12 18:30:21 -050056 adbloginit();
57}
58
59twrpback::~twrpback(void) {
60 adblogfile.close();
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040061 closeFifos();
62}
63
bigbiff bigbiff38b83c12017-12-28 19:58:52 -050064void twrpback::printErrMsg(std::string msg, int errNum) {
65 std::stringstream str;
66 str << strerror(errNum);
67 adblogwrite(msg + " " + str.str() + "\n");
68}
69
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040070void twrpback::createFifos(void) {
71 if (mkfifo(TW_ADB_BU_CONTROL, 0666) < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -050072 std::string msg = "Unable to create TW_ADB_BU_CONTROL fifo: ";
73 printErrMsg(msg, errno);
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040074 }
75 if (mkfifo(TW_ADB_TWRP_CONTROL, 0666) < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -050076 std::string msg = "Unable to create TW_ADB_TWRP_CONTROL fifo: ";
77 printErrMsg(msg, errno);
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040078 unlink(TW_ADB_BU_CONTROL);
79 }
80}
81
82void twrpback::closeFifos(void) {
83 if (unlink(TW_ADB_BU_CONTROL) < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -050084 std::string msg = "Unable to remove TW_ADB_BU_CONTROL: ";
85 printErrMsg(msg, errno);
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040086 }
87 if (unlink(TW_ADB_TWRP_CONTROL) < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -050088 std::string msg = "Unable to remove TW_ADB_TWRP_CONTROL: ";
89 printErrMsg(msg, errno);
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040090 }
bigbiffce8f83c2015-12-12 18:30:21 -050091}
92
93void twrpback::adbloginit(void) {
94 adblogfile.open("/tmp/adb.log", std::fstream::app);
95}
96
97void twrpback::adblogwrite(std::string writemsg) {
98 adblogfile << writemsg << std::flush;
99}
100
101void twrpback::close_backup_fds() {
102 if (ors_fd > 0)
103 close(ors_fd);
104 if (write_fd > 0)
105 close(write_fd);
106 if (adb_read_fd > 0)
107 close(adb_read_fd);
108 if (adb_control_bu_fd > 0)
109 close(adb_control_bu_fd);
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500110 #ifdef _DEBUG_ADB_BACKUP
111 if (debug_adb_fd > 0)
112 close(debug_adb_fd);
113 #endif
bigbiffce8f83c2015-12-12 18:30:21 -0500114 if (adbd_fp != NULL)
115 fclose(adbd_fp);
116 if (access(TW_ADB_BACKUP, F_OK) == 0)
117 unlink(TW_ADB_BACKUP);
118}
119
120void twrpback::close_restore_fds() {
121 if (ors_fd > 0)
122 close(ors_fd);
123 if (write_fd > 0)
124 close(write_fd);
125 if (adb_control_bu_fd > 0)
126 close(adb_control_bu_fd);
127 if (adb_control_twrp_fd > 0)
128 close(adb_control_twrp_fd);
129 if (adbd_fp != NULL)
130 fclose(adbd_fp);
131 if (access(TW_ADB_RESTORE, F_OK) == 0)
132 unlink(TW_ADB_RESTORE);
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500133 #ifdef _DEBUG_ADB_BACKUP
134 if (debug_adb_fd > 0)
135 close(debug_adb_fd);
136 #endif
bigbiffce8f83c2015-12-12 18:30:21 -0500137}
138
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400139bool twrpback::backup(std::string command) {
bigbiff bigbiff56cf5642016-08-19 17:43:45 -0400140 twrpMD5 digest;
bigbiffce8f83c2015-12-12 18:30:21 -0500141 int bytes = 0, errctr = 0;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400142 char adbReadStream[MAX_ADB_READ];
143 uint64_t totalbytes = 0, dataChunkBytes = 0, fileBytes = 0;
bigbiffce8f83c2015-12-12 18:30:21 -0500144 uint64_t md5fnsize = 0;
145 struct AdbBackupControlType endadb;
146
Ethan Yonker58f21322018-08-24 11:17:36 -0500147 //ADBSTRUCT_STATIC_ASSERT(sizeof(endadb) == MAX_ADB_READ);
bigbiffce8f83c2015-12-12 18:30:21 -0500148
149 bool writedata = true;
150 bool compressed = false;
151 bool firstDataPacket = true;
152
153 adbd_fp = fdopen(adbd_fd, "w");
154 if (adbd_fp == NULL) {
155 adblogwrite("Unable to open adb_fp\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400156 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500157 }
158
159 if (mkfifo(TW_ADB_BACKUP, 0666) < 0) {
160 adblogwrite("Unable to create TW_ADB_BACKUP fifo\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400161 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500162 }
163
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400164 adblogwrite("opening TW_ADB_FIFO\n");
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500165
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400166 write_fd = open(TW_ADB_FIFO, O_WRONLY);
bigbiffce8f83c2015-12-12 18:30:21 -0500167 while (write_fd < 0) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400168 write_fd = open(TW_ADB_FIFO, O_WRONLY);
bigbiffce8f83c2015-12-12 18:30:21 -0500169 usleep(10000);
170 errctr++;
171 if (errctr > ADB_BU_MAX_ERROR) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500172 std::string msg = "Unable to open TW_ADB_FIFO";
173 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500174 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400175 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500176 }
177 }
178
Ayke van Laethem05c2de42017-06-02 00:19:27 +0200179 memset(operation, 0, sizeof(operation));
Ethan Yonker58f21322018-08-24 11:17:36 -0500180 if (snprintf(operation, sizeof(operation), "adbbackup %s", command.c_str()) >= (int)sizeof(operation)) {
Ayke van Laethem05c2de42017-06-02 00:19:27 +0200181 adblogwrite("Operation too big to write to ORS_INPUT_FILE\n");
182 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400183 return false;
Ayke van Laethem05c2de42017-06-02 00:19:27 +0200184 }
bigbiffce8f83c2015-12-12 18:30:21 -0500185 if (write(write_fd, operation, sizeof(operation)) != sizeof(operation)) {
186 adblogwrite("Unable to write to ORS_INPUT_FILE\n");
187 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400188 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500189 }
190
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400191 memset(&adbReadStream, 0, sizeof(adbReadStream));
bigbiffce8f83c2015-12-12 18:30:21 -0500192 memset(&cmd, 0, sizeof(cmd));
193
194 adblogwrite("opening TW_ADB_BU_CONTROL\n");
195 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_RDONLY | O_NONBLOCK);
196 if (adb_control_bu_fd < 0) {
197 adblogwrite("Unable to open TW_ADB_BU_CONTROL for reading.\n");
198 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400199 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500200 }
201
202 adblogwrite("opening TW_ADB_BACKUP\n");
203 adb_read_fd = open(TW_ADB_BACKUP, O_RDONLY | O_NONBLOCK);
204 if (adb_read_fd < 0) {
205 adblogwrite("Unable to open TW_ADB_BACKUP for reading.\n");
206 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400207 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500208 }
209
210 //loop until TWENDADB sent
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500211 while (true) {
bigbiffce8f83c2015-12-12 18:30:21 -0500212 if (read(adb_control_bu_fd, &cmd, sizeof(cmd)) > 0) {
213 struct AdbBackupControlType structcmd;
214
215 memcpy(&structcmd, cmd, sizeof(cmd));
Ayke van Laethem05c2de42017-06-02 00:19:27 +0200216 std::string cmdtype = structcmd.get_type();
bigbiffce8f83c2015-12-12 18:30:21 -0500217
218 //we received an error, exit and unlink
219 if (cmdtype == TWERROR) {
220 writedata = false;
221 adblogwrite("Error received. Quitting...\n");
222 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400223 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500224 }
225 //we received the end of adb backup stream so we should break the loop
226 else if (cmdtype == TWENDADB) {
227 writedata = false;
228 adblogwrite("Recieved TWENDADB\n");
229 memcpy(&endadb, cmd, sizeof(cmd));
Matt Mowercc19c6f2017-02-22 11:31:35 -0600230 std::stringstream str;
bigbiffce8f83c2015-12-12 18:30:21 -0500231 str << totalbytes;
232 adblogwrite(str.str() + " total bytes written\n");
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500233 break;
bigbiffce8f83c2015-12-12 18:30:21 -0500234 }
235 //we recieved the TWSTREAMHDR structure metadata to write to adb
236 else if (cmdtype == TWSTREAMHDR) {
237 writedata = false;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400238 adblogwrite("writing TWSTREAMHDR\n");
bigbiffce8f83c2015-12-12 18:30:21 -0500239 if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500240 std::string msg = "Error writing TWSTREAMHDR to adbd";
241 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500242 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400243 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500244 }
245 fflush(adbd_fp);
246 }
247 //we will be writing an image from TWRP
248 else if (cmdtype == TWIMG) {
249 struct twfilehdr twimghdr;
250
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400251 adblogwrite("writing TWIMG\n");
bigbiff bigbiff56cf5642016-08-19 17:43:45 -0400252 digest.init();
bigbiffce8f83c2015-12-12 18:30:21 -0500253 memset(&twimghdr, 0, sizeof(twimghdr));
254 memcpy(&twimghdr, cmd, sizeof(cmd));
255 md5fnsize = twimghdr.size;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400256 compressed = false;
bigbiffce8f83c2015-12-12 18:30:21 -0500257
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500258 #ifdef _DEBUG_ADB_BACKUP
259 std::string debug_fname = "/data/media/";
260 debug_fname.append(basename(twimghdr.name));
261 debug_fname.append("-backup.img");
262 debug_adb_fd = open(debug_fname.c_str(), O_WRONLY | O_CREAT, 0666);
263 adblogwrite("Opening adb debug tar\n");
264 #endif
265
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400266 if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) {
bigbiffce8f83c2015-12-12 18:30:21 -0500267 adblogwrite("Error writing TWIMG to adbd\n");
268 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400269 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500270 }
271 fflush(adbd_fp);
272 writedata = true;
273 }
274 //we will be writing a tar from TWRP
275 else if (cmdtype == TWFN) {
276 struct twfilehdr twfilehdr;
277
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400278 adblogwrite("writing TWFN\n");
bigbiff bigbiff56cf5642016-08-19 17:43:45 -0400279 digest.init();
bigbiffce8f83c2015-12-12 18:30:21 -0500280
Ethan Yonker58f21322018-08-24 11:17:36 -0500281 //ADBSTRUCT_STATIC_ASSERT(sizeof(twfilehdr) == MAX_ADB_READ);
bigbiffce8f83c2015-12-12 18:30:21 -0500282
283 memset(&twfilehdr, 0, sizeof(twfilehdr));
284 memcpy(&twfilehdr, cmd, sizeof(cmd));
285 md5fnsize = twfilehdr.size;
286
287 compressed = twfilehdr.compressed == 1 ? true: false;
288
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500289 #ifdef _DEBUG_ADB_BACKUP
290 std::string debug_fname = "/data/media/";
291 debug_fname.append(basename(twfilehdr.name));
292 debug_fname.append("-backup.tar");
293 debug_adb_fd = open(debug_fname.c_str(), O_WRONLY | O_CREAT, 0666);
294 adblogwrite("Opening adb debug tar\n");
295 #endif
296
bigbiffce8f83c2015-12-12 18:30:21 -0500297 if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) {
298 adblogwrite("Error writing TWFN to adbd\n");
299 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400300 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500301 }
302 fflush(adbd_fp);
303 writedata = true;
304 }
305 /*
306 We received the command that we are done with the file stream.
307 We will flush the remaining data stream.
308 Update md5 and write final results to adb stream.
309 If we need padding because the total bytes are not a multiple
310 of 512, we pad the end with 0s to we reach 512.
311 We also write the final md5 to the adb stream.
312 */
313 else if (cmdtype == TWEOF) {
314 adblogwrite("received TWEOF\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400315 while ((bytes = read(adb_read_fd, &adbReadStream, sizeof(adbReadStream)) != 0)) {
bigbiffce8f83c2015-12-12 18:30:21 -0500316 totalbytes += bytes;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400317 fileBytes += bytes;
318 dataChunkBytes += bytes;
319
320 char *writeAdbReadStream = new char [bytes];
321 memcpy(writeAdbReadStream, adbReadStream, bytes);
322
323 digest.update((unsigned char *) writeAdbReadStream, bytes);
324 if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500325 std::string msg = "Cannot write to adbd stream: ";
326 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500327 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500328 #if defined(_DEBUG_ADB_BACKUP)
329 if (write(debug_adb_fd, writeAdbReadStream, bytes) < 1) {
330 std::string msg = "Cannot write to ADB_CONTROL_READ_FD: ";
331 printErrMsg(msg, errno);
332 close_restore_fds();
333 return false;
334 }
335 #endif
bigbiffce8f83c2015-12-12 18:30:21 -0500336 fflush(adbd_fp);
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400337 delete [] writeAdbReadStream;
338 memset(adbReadStream, 0, sizeof(adbReadStream));
bigbiffce8f83c2015-12-12 18:30:21 -0500339 }
340
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400341 if (fileBytes % DATA_MAX_CHUNK_SIZE != 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500342 int64_t count = fileBytes / DATA_MAX_CHUNK_SIZE + 1;
343 uint64_t ceilingBytes = count * DATA_MAX_CHUNK_SIZE;
344 char padding[ceilingBytes - fileBytes];
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400345 int paddingBytes = sizeof(padding);
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500346 memset(padding, 0, paddingBytes);
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400347 std::stringstream paddingStr;
348 paddingStr << paddingBytes;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400349 adblogwrite("writing padding to stream: " + paddingStr.str() + " bytes\n");
350 if (fwrite(padding, 1, paddingBytes, adbd_fp) != sizeof(padding)) {
bigbiffce8f83c2015-12-12 18:30:21 -0500351 adblogwrite("Error writing padding to adbd\n");
352 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400353 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500354 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500355 #if defined(_DEBUG_ADB_BACKUP)
356 if (write(debug_adb_fd, padding, paddingBytes) < 1) {
357 std::string msg = "Cannot write to ADB_CONTROL_READ_FD: ";
358 printErrMsg(msg, errno);
359 close_restore_fds();
360 return false;
361 }
362 #endif
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400363 totalbytes += paddingBytes;
364 digest.update((unsigned char *) padding, paddingBytes);
bigbiffce8f83c2015-12-12 18:30:21 -0500365 fflush(adbd_fp);
bigbiffce8f83c2015-12-12 18:30:21 -0500366 }
367
368 AdbBackupFileTrailer md5trailer;
369
370 memset(&md5trailer, 0, sizeof(md5trailer));
bigbiffce8f83c2015-12-12 18:30:21 -0500371
bigbiff bigbiff56cf5642016-08-19 17:43:45 -0400372 std::string md5string = digest.return_digest_string();
bigbiffce8f83c2015-12-12 18:30:21 -0500373
374 strncpy(md5trailer.start_of_trailer, TWRP, sizeof(md5trailer.start_of_trailer));
375 strncpy(md5trailer.type, MD5TRAILER, sizeof(md5trailer.type));
376 strncpy(md5trailer.md5, md5string.c_str(), sizeof(md5trailer.md5));
377
378 md5trailer.crc = crc32(0L, Z_NULL, 0);
379 md5trailer.crc = crc32(md5trailer.crc, (const unsigned char*) &md5trailer, sizeof(md5trailer));
380
381 md5trailer.ident = crc32(0L, Z_NULL, 0);
382 md5trailer.ident = crc32(md5trailer.ident, (const unsigned char*) &md5trailer, sizeof(md5trailer));
383 md5trailer.ident = crc32(md5trailer.ident, (const unsigned char*) &md5fnsize, sizeof(md5fnsize));
384
385 if (fwrite(&md5trailer, 1, sizeof(md5trailer), adbd_fp) != sizeof(md5trailer)) {
386 adblogwrite("Error writing md5trailer to adbd\n");
387 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400388 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500389 }
390 fflush(adbd_fp);
391 writedata = false;
392 firstDataPacket = true;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400393 fileBytes = 0;
bigbiffce8f83c2015-12-12 18:30:21 -0500394 }
395 memset(&cmd, 0, sizeof(cmd));
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500396 dataChunkBytes = 0;
bigbiffce8f83c2015-12-12 18:30:21 -0500397 }
398 //If we are to write data because of a new file stream, lets write all the data.
399 //This will allow us to not write data after a command structure has been written
400 //to the adb stream.
401 //If the stream is compressed, we need to always write the data.
402 if (writedata || compressed) {
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400403 while ((bytes = read(adb_read_fd, &adbReadStream, sizeof(adbReadStream))) > 0) {
bigbiffce8f83c2015-12-12 18:30:21 -0500404 if (firstDataPacket) {
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400405 if (!twadbbu::Write_TWDATA(adbd_fp)) {
bigbiffce8f83c2015-12-12 18:30:21 -0500406 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400407 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500408 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500409 fileBytes += MAX_ADB_READ;
bigbiffce8f83c2015-12-12 18:30:21 -0500410 fflush(adbd_fp);
411 firstDataPacket = false;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400412 dataChunkBytes += sizeof(adbReadStream);
bigbiffce8f83c2015-12-12 18:30:21 -0500413 }
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400414 char *writeAdbReadStream = new char [bytes];
415 memcpy(writeAdbReadStream, adbReadStream, bytes);
bigbiffce8f83c2015-12-12 18:30:21 -0500416
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400417 digest.update((unsigned char *) writeAdbReadStream, bytes);
bigbiffce8f83c2015-12-12 18:30:21 -0500418
419 totalbytes += bytes;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400420 fileBytes += bytes;
bigbiffce8f83c2015-12-12 18:30:21 -0500421 dataChunkBytes += bytes;
422
Ethan Yonker58f21322018-08-24 11:17:36 -0500423 if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) != (unsigned long long)bytes) {
bigbiffce8f83c2015-12-12 18:30:21 -0500424 adblogwrite("Error writing backup data to adbd\n");
425 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400426 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500427 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500428 #ifdef _DEBUG_ADB_BACKUP
429 if (write(debug_adb_fd, writeAdbReadStream, bytes) < 1) {
430 std::string msg = "Cannot write to ADB_CONTROL_READ_FD: ";
431 printErrMsg(msg, errno);
432 close_restore_fds();
433 return false;
434 }
435 #endif
bigbiffce8f83c2015-12-12 18:30:21 -0500436 fflush(adbd_fp);
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400437 delete [] writeAdbReadStream;
bigbiffce8f83c2015-12-12 18:30:21 -0500438
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400439 memset(&adbReadStream, 0, sizeof(adbReadStream));
bigbiffce8f83c2015-12-12 18:30:21 -0500440
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400441 if (dataChunkBytes == DATA_MAX_CHUNK_SIZE) {
442 dataChunkBytes = 0;
443 firstDataPacket = true;
444 }
445 else if (dataChunkBytes > (DATA_MAX_CHUNK_SIZE - sizeof(adbReadStream))) {
446 int bytesLeft = DATA_MAX_CHUNK_SIZE - dataChunkBytes;
447 char extraData[bytesLeft];
448
449 memset(&extraData, 0, bytesLeft);
450 while ((bytes = read(adb_read_fd, &extraData, bytesLeft)) != 0) {
451 if (bytes > 0) {
452 totalbytes += bytes;
453 fileBytes += bytes;
454 dataChunkBytes += bytes;
455
456 bytesLeft -= bytes;
457 char *writeAdbReadStream = new char [bytes];
458 memcpy(writeAdbReadStream, extraData, bytes);
459
460 digest.update((unsigned char *) writeAdbReadStream, bytes);
461 if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500462 std::string msg = "Cannot write to adbd stream: ";
463 printErrMsg(msg, errno);
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400464 close_restore_fds();
465 return false;
466 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500467 #ifdef _DEBUG_ADB_BACKUP
468 if (write(debug_adb_fd, writeAdbReadStream, bytes) < 1) {
469 std::string msg = "Cannot write to ADB_CONTROL_READ_FD: ";
470 printErrMsg(msg, errno);
471 close_restore_fds();
472 return false;
473 }
474 #endif
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400475 fflush(adbd_fp);
476 delete [] writeAdbReadStream;
477 }
478 memset(&extraData, 0, bytesLeft);
479 if (bytesLeft == 0) {
480 break;
481 }
bigbiffce8f83c2015-12-12 18:30:21 -0500482 }
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400483
bigbiffce8f83c2015-12-12 18:30:21 -0500484 fflush(adbd_fp);
485 dataChunkBytes = 0;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400486 firstDataPacket = true;
bigbiffce8f83c2015-12-12 18:30:21 -0500487 }
bigbiffce8f83c2015-12-12 18:30:21 -0500488 }
bigbiffce8f83c2015-12-12 18:30:21 -0500489 }
490 }
491
492 //Write the final end adb structure to the adb stream
493 if (fwrite(&endadb, 1, sizeof(endadb), adbd_fp) != sizeof(endadb)) {
494 adblogwrite("Error writing endadb to adbd\n");
495 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400496 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500497 }
498 fflush(adbd_fp);
499 close_backup_fds();
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500500 return true;
bigbiffce8f83c2015-12-12 18:30:21 -0500501}
502
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400503bool twrpback::restore(void) {
bigbiff bigbiff56cf5642016-08-19 17:43:45 -0400504 twrpMD5 digest;
505 char cmd[MAX_ADB_READ];
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400506 char readAdbStream[MAX_ADB_READ];
bigbiffce8f83c2015-12-12 18:30:21 -0500507 struct AdbBackupControlType structcmd;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400508 int errctr = 0;
bigbiffce8f83c2015-12-12 18:30:21 -0500509 uint64_t totalbytes = 0, dataChunkBytes = 0;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500510 uint64_t md5fnsize = 0, fileBytes = 0;
Ethan Yonker58f21322018-08-24 11:17:36 -0500511 bool read_from_adb;
512 bool md5sumdata;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500513 bool compressed, tweofrcvd, extraData;
bigbiffce8f83c2015-12-12 18:30:21 -0500514
bigbiffce8f83c2015-12-12 18:30:21 -0500515 read_from_adb = true;
516
517 signal(SIGPIPE, SIG_IGN);
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500518 signal(SIGHUP, SIG_IGN);
bigbiffce8f83c2015-12-12 18:30:21 -0500519
520 adbd_fp = fdopen(adbd_fd, "r");
521 if (adbd_fp == NULL) {
522 adblogwrite("Unable to open adb_fp\n");
523 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400524 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500525 }
526
527 if(mkfifo(TW_ADB_RESTORE, 0666)) {
528 adblogwrite("Unable to create TW_ADB_RESTORE fifo\n");
529 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400530 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500531 }
532
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400533 adblogwrite("opening TW_ADB_FIFO\n");
534 write_fd = open(TW_ADB_FIFO, O_WRONLY);
bigbiffce8f83c2015-12-12 18:30:21 -0500535
536 while (write_fd < 0) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400537 write_fd = open(TW_ADB_FIFO, O_WRONLY);
bigbiffce8f83c2015-12-12 18:30:21 -0500538 errctr++;
539 if (errctr > ADB_BU_MAX_ERROR) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500540 std::string msg = "Unable to open TW_ADB_FIFO.";
541 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500542 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400543 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500544 }
545 }
546
Ayke van Laethem05c2de42017-06-02 00:19:27 +0200547 memset(operation, 0, sizeof(operation));
bigbiffce8f83c2015-12-12 18:30:21 -0500548 sprintf(operation, "adbrestore");
549 if (write(write_fd, operation, sizeof(operation)) != sizeof(operation)) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400550 adblogwrite("Unable to write to TW_ADB_FIFO\n");
bigbiffce8f83c2015-12-12 18:30:21 -0500551 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400552 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500553 }
554
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400555 memset(&readAdbStream, 0, sizeof(readAdbStream));
bigbiffce8f83c2015-12-12 18:30:21 -0500556 memset(&cmd, 0, sizeof(cmd));
557
558 adblogwrite("opening TW_ADB_BU_CONTROL\n");
559 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_RDONLY | O_NONBLOCK);
560 if (adb_control_bu_fd < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500561 std::string msg = "Unable to open TW_ADB_BU_CONTROL for writing.";
562 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500563 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400564 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500565 }
566
567 adblogwrite("opening TW_ADB_TWRP_CONTROL\n");
568 adb_control_twrp_fd = open(TW_ADB_TWRP_CONTROL, O_WRONLY | O_NONBLOCK);
569 if (adb_control_twrp_fd < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500570 std::string msg = "Unable to open TW_ADB_TWRP_CONTROL for writing. Retrying...";
571 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500572 while (adb_control_twrp_fd < 0) {
573 adb_control_twrp_fd = open(TW_ADB_TWRP_CONTROL, O_WRONLY | O_NONBLOCK);
574 usleep(10000);
575 errctr++;
576 if (errctr > ADB_BU_MAX_ERROR) {
577 adblogwrite("Unable to open TW_ADB_TWRP_CONTROL\n");
578 close_backup_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400579 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500580 }
581 }
582 }
583
584 //Loop until we receive TWENDADB from TWRP
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500585 while (true) {
bigbiffce8f83c2015-12-12 18:30:21 -0500586 memset(&cmd, 0, sizeof(cmd));
587 if (read(adb_control_bu_fd, &cmd, sizeof(cmd)) > 0) {
588 struct AdbBackupControlType structcmd;
589 memcpy(&structcmd, cmd, sizeof(cmd));
Ayke van Laethem05c2de42017-06-02 00:19:27 +0200590 std::string cmdtype = structcmd.get_type();
bigbiffce8f83c2015-12-12 18:30:21 -0500591
592 //If we receive TWEOF from TWRP close adb data fifo
593 if (cmdtype == TWEOF) {
594 adblogwrite("Received TWEOF\n");
bigbiffce8f83c2015-12-12 18:30:21 -0500595 read_from_adb = true;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500596 tweofrcvd = true;
597 close(adb_write_fd);
bigbiffce8f83c2015-12-12 18:30:21 -0500598 }
599 //Break when TWRP sends TWENDADB
600 else if (cmdtype == TWENDADB) {
601 adblogwrite("Received TWENDADB\n");
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500602 break;
bigbiffce8f83c2015-12-12 18:30:21 -0500603 }
604 //we received an error, exit and unlink
605 else if (cmdtype == TWERROR) {
606 adblogwrite("Error received. Quitting...\n");
607 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400608 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500609 }
610 }
bigbiffce8f83c2015-12-12 18:30:21 -0500611 //If we should read from the adb stream, write commands and data to TWRP
612 if (read_from_adb) {
bigbiffce8f83c2015-12-12 18:30:21 -0500613 int readbytes;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400614 if ((readbytes = fread(readAdbStream, 1, sizeof(readAdbStream), adbd_fp)) == sizeof(readAdbStream)) {
615 memcpy(&structcmd, readAdbStream, sizeof(readAdbStream));
Ayke van Laethem05c2de42017-06-02 00:19:27 +0200616 std::string cmdtype = structcmd.get_type();
bigbiffce8f83c2015-12-12 18:30:21 -0500617
618 //Tell TWRP we have read the entire adb stream
619 if (cmdtype == TWENDADB) {
620 struct AdbBackupControlType endadb;
621 uint32_t crc, endadbcrc;
622
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500623 md5sumdata = false;
bigbiffce8f83c2015-12-12 18:30:21 -0500624 memset(&endadb, 0, sizeof(endadb));
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400625 memcpy(&endadb, readAdbStream, sizeof(readAdbStream));
bigbiffce8f83c2015-12-12 18:30:21 -0500626 endadbcrc = endadb.crc;
627 memset(&endadb.crc, 0, sizeof(endadb.crc));
628 crc = crc32(0L, Z_NULL, 0);
629 crc = crc32(crc, (const unsigned char*) &endadb, sizeof(endadb));
630
631 if (crc == endadbcrc) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500632 adblogwrite("sending TWENDADB\n");
bigbiffce8f83c2015-12-12 18:30:21 -0500633 if (write(adb_control_twrp_fd, &endadb, sizeof(endadb)) < 1) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500634 std::string msg = "Cannot write to ADB_CONTROL_READ_FD: ";
635 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500636 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400637 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500638 }
bigbiff bigbiffb5ecaad2017-03-20 18:53:53 -0400639 read_from_adb = false;
bigbiffce8f83c2015-12-12 18:30:21 -0500640 }
641 else {
642 adblogwrite("ADB TWENDADB crc header doesn't match\n");
643 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400644 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500645 }
646 }
647 //Send TWRP partition metadata
648 else if (cmdtype == TWSTREAMHDR) {
649 struct AdbBackupStreamHeader cnthdr;
650 uint32_t crc, cnthdrcrc;
651
Ethan Yonker58f21322018-08-24 11:17:36 -0500652 //ADBSTRUCT_STATIC_ASSERT(sizeof(cnthdr) == MAX_ADB_READ);
bigbiffce8f83c2015-12-12 18:30:21 -0500653
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500654 md5sumdata = false;
bigbiffce8f83c2015-12-12 18:30:21 -0500655 memset(&cnthdr, 0, sizeof(cnthdr));
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400656 memcpy(&cnthdr, readAdbStream, sizeof(readAdbStream));
bigbiffce8f83c2015-12-12 18:30:21 -0500657 cnthdrcrc = cnthdr.crc;
658 memset(&cnthdr.crc, 0, sizeof(cnthdr.crc));
659 crc = crc32(0L, Z_NULL, 0);
660 crc = crc32(crc, (const unsigned char*) &cnthdr, sizeof(cnthdr));
661
662 if (crc == cnthdrcrc) {
663 adblogwrite("Restoring TWSTREAMHDR\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400664 if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500665 std::string msg = "Cannot write to adb_control_twrp_fd: ";
666 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500667 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400668 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500669 }
670 }
671 else {
672 adblogwrite("ADB TWSTREAMHDR crc header doesn't match\n");
673 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400674 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500675 }
676 }
677 //Tell TWRP we are sending a partition image
678 else if (cmdtype == TWIMG) {
679 struct twfilehdr twimghdr;
680 uint32_t crc, twimghdrcrc;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500681 md5sumdata = false;
682 fileBytes = 0;
683 read_from_adb = true;
684 dataChunkBytes = 0;
685 extraData = false;
bigbiffce8f83c2015-12-12 18:30:21 -0500686
bigbiff bigbiff56cf5642016-08-19 17:43:45 -0400687 digest.init();
bigbiffce8f83c2015-12-12 18:30:21 -0500688 adblogwrite("Restoring TWIMG\n");
689 memset(&twimghdr, 0, sizeof(twimghdr));
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400690 memcpy(&twimghdr, readAdbStream, sizeof(readAdbStream));
bigbiffce8f83c2015-12-12 18:30:21 -0500691 md5fnsize = twimghdr.size;
692 twimghdrcrc = twimghdr.crc;
693 memset(&twimghdr.crc, 0, sizeof(twimghdr.crc));
694
695 crc = crc32(0L, Z_NULL, 0);
696 crc = crc32(crc, (const unsigned char*) &twimghdr, sizeof(twimghdr));
697 if (crc == twimghdrcrc) {
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400698 if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500699 std::string msg = "Cannot write to adb_control_twrp_fd: ";
700 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500701 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400702 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500703 }
704 }
705 else {
706 adblogwrite("ADB TWIMG crc header doesn't match\n");
707 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400708 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500709 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500710
711 #ifdef _DEBUG_ADB_BACKUP
712 std::string debug_fname = "/data/media/";
713 debug_fname.append(basename(twimghdr.name));
714 debug_fname.append("-restore.img");
715 adblogwrite("image: " + debug_fname + "\n");
716 debug_adb_fd = open(debug_fname.c_str(), O_WRONLY | O_CREAT, 0666);
717 adblogwrite("Opened restore image\n");
718 #endif
719
bigbiffce8f83c2015-12-12 18:30:21 -0500720 adblogwrite("opening TW_ADB_RESTORE\n");
721 adb_write_fd = open(TW_ADB_RESTORE, O_WRONLY);
722 }
723 //Tell TWRP we are sending a tar stream
724 else if (cmdtype == TWFN) {
725 struct twfilehdr twfilehdr;
726 uint32_t crc, twfilehdrcrc;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500727 fileBytes = 0;
728 md5sumdata = false;
729 read_from_adb = true;
730 dataChunkBytes = 0;
731 extraData = false;
bigbiffce8f83c2015-12-12 18:30:21 -0500732
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400733 digest.init();
bigbiffce8f83c2015-12-12 18:30:21 -0500734 adblogwrite("Restoring TWFN\n");
735 memset(&twfilehdr, 0, sizeof(twfilehdr));
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400736 memcpy(&twfilehdr, readAdbStream, sizeof(readAdbStream));
bigbiffce8f83c2015-12-12 18:30:21 -0500737 md5fnsize = twfilehdr.size;
738 twfilehdrcrc = twfilehdr.crc;
739 memset(&twfilehdr.crc, 0, sizeof(twfilehdr.crc));
740
741 crc = crc32(0L, Z_NULL, 0);
742 crc = crc32(crc, (const unsigned char*) &twfilehdr, sizeof(twfilehdr));
743
744 if (crc == twfilehdrcrc) {
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400745 if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500746 std::string msg = "Cannot write to adb_control_twrp_fd: ";
747 printErrMsg(msg, errno);
bigbiffce8f83c2015-12-12 18:30:21 -0500748 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400749 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500750 }
751 }
752 else {
753 adblogwrite("ADB TWFN crc header doesn't match\n");
754 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400755 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500756 }
757
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500758 #ifdef _DEBUG_ADB_BACKUP
759 std::string debug_fname = "/data/media/";
760 debug_fname.append(basename(twfilehdr.name));
761 debug_fname.append("-restore.tar");
762 adblogwrite("tar: " + debug_fname + "\n");
763 debug_adb_fd = open(debug_fname.c_str(), O_WRONLY | O_CREAT, 0666);
764 adblogwrite("Opened restore tar\n");
765 #endif
766
767 compressed = twfilehdr.compressed == 1 ? true: false;
bigbiffce8f83c2015-12-12 18:30:21 -0500768 adblogwrite("opening TW_ADB_RESTORE\n");
769 adb_write_fd = open(TW_ADB_RESTORE, O_WRONLY);
770 }
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400771 else if (cmdtype == MD5TRAILER) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500772 if (fileBytes >= md5fnsize)
773 close(adb_write_fd);
774 if (tweofrcvd) {
775 read_from_adb = true;
776 tweofrcvd = false;
777 }
778 else
779 read_from_adb = false; //don't read from adb until TWRP sends TWEOF
780 md5sumdata = false;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400781 if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) {
782 close_restore_fds();
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500783 break;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400784 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500785 continue;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400786 }
bigbiffce8f83c2015-12-12 18:30:21 -0500787 //Send the tar or partition image md5 to TWRP
788 else if (cmdtype == TWDATA) {
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400789 dataChunkBytes += sizeof(readAdbStream);
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500790 while (true) {
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400791 if ((readbytes = fread(readAdbStream, 1, sizeof(readAdbStream), adbd_fp)) != sizeof(readAdbStream)) {
bigbiffce8f83c2015-12-12 18:30:21 -0500792 close_restore_fds();
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400793 return false;
bigbiffce8f83c2015-12-12 18:30:21 -0500794 }
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400795 memcpy(&structcmd, readAdbStream, sizeof(readAdbStream));
Ayke van Laethem05c2de42017-06-02 00:19:27 +0200796 std::string cmdtype = structcmd.get_type();
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500797
bigbiffce8f83c2015-12-12 18:30:21 -0500798 dataChunkBytes += readbytes;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400799 totalbytes += readbytes;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500800 fileBytes += readbytes;
bigbiffce8f83c2015-12-12 18:30:21 -0500801
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400802 if (cmdtype == MD5TRAILER) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500803 if (fileBytes >= md5fnsize)
804 close(adb_write_fd);
805 if (tweofrcvd) {
806 tweofrcvd = false;
807 read_from_adb = true;
808 }
809 else
810 read_from_adb = false; //don't read from adb until TWRP sends TWEOF
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400811 if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) {
812 close_restore_fds();
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500813 break;
bigbiffce8f83c2015-12-12 18:30:21 -0500814 }
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400815 break;
bigbiffce8f83c2015-12-12 18:30:21 -0500816 }
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400817
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500818 digest.update((unsigned char*)readAdbStream, readbytes);
819
820 read_from_adb = true;
821
822 #ifdef _DEBUG_ADB_BACKUP
823 if (write(debug_adb_fd, readAdbStream, sizeof(readAdbStream)) < 0) {
824 std::string msg = "Cannot write to ADB_CONTROL_READ_FD: ";
825 printErrMsg(msg, errno);
826 close_restore_fds();
827 return false;
828 }
829 #endif
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400830
831 if (write(adb_write_fd, readAdbStream, sizeof(readAdbStream)) < 0) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500832 std::string msg = "Cannot write to TWRP ADB FIFO: ";
833 md5sumdata = true;
834 printErrMsg(msg, errno);
835 adblogwrite("end of stream reached.\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400836 break;
837 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500838
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400839 if (dataChunkBytes == DATA_MAX_CHUNK_SIZE) {
bigbiffce8f83c2015-12-12 18:30:21 -0500840 dataChunkBytes = 0;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500841 md5sumdata = false;
bigbiffce8f83c2015-12-12 18:30:21 -0500842 break;
843 }
bigbiffce8f83c2015-12-12 18:30:21 -0500844 }
845 }
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500846 else if (md5sumdata) {
847 digest.update((unsigned char*)readAdbStream, sizeof(readAdbStream));
848 md5sumdata = true;
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400849 }
bigbiffce8f83c2015-12-12 18:30:21 -0500850 }
851 }
852 }
Matt Mowercc19c6f2017-02-22 11:31:35 -0600853 std::stringstream str;
bigbiffce8f83c2015-12-12 18:30:21 -0500854 str << totalbytes;
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500855 close_restore_fds();
bigbiffce8f83c2015-12-12 18:30:21 -0500856 adblogwrite(str.str() + " bytes restored from adbbackup\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400857 return true;
bigbiffce8f83c2015-12-12 18:30:21 -0500858}
859
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400860void twrpback::streamFileForTWRP(void) {
861 adblogwrite("streamFileForTwrp" + streamFn + "\n");
862}
bigbiffce8f83c2015-12-12 18:30:21 -0500863
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400864void twrpback::setStreamFileName(std::string fn) {
865 streamFn = fn;
866 adbd_fd = open(fn.c_str(), O_RDONLY);
867 if (adbd_fd < 0) {
868 adblogwrite("Unable to open adb_fd\n");
869 close(adbd_fd);
870 return;
bigbiffce8f83c2015-12-12 18:30:21 -0500871 }
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400872 restore();
873}
bigbiffce8f83c2015-12-12 18:30:21 -0500874
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400875void twrpback::threadStream(void) {
876 pthread_t thread;
877 ThreadPtr streamPtr = &twrpback::streamFileForTWRP;
878 PThreadPtr p = *(PThreadPtr*)&streamPtr;
879 pthread_create(&thread, NULL, p, this);
880 pthread_join(thread, NULL);
bigbiffce8f83c2015-12-12 18:30:21 -0500881}
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400882
883bool twrpback::checkMD5Trailer(char readAdbStream[], uint64_t md5fnsize, twrpMD5 *digest) {
884 struct AdbBackupFileTrailer md5tr;
885 uint32_t crc, md5trcrc, md5ident, md5identmatch;
886
Ethan Yonker58f21322018-08-24 11:17:36 -0500887 //ADBSTRUCT_STATIC_ASSERT(sizeof(md5tr) == MAX_ADB_READ);
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400888 memcpy(&md5tr, readAdbStream, MAX_ADB_READ);
889 md5ident = md5tr.ident;
890
891 memset(&md5tr.ident, 0, sizeof(md5tr.ident));
892
893 md5identmatch = crc32(0L, Z_NULL, 0);
894 md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5tr, sizeof(md5tr));
895 md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5fnsize, sizeof(md5fnsize));
896
897 if (md5identmatch == md5ident) {
898 adblogwrite("checking MD5TRAILER\n");
899 md5trcrc = md5tr.crc;
900 memset(&md5tr.crc, 0, sizeof(md5tr.crc));
901 crc = crc32(0L, Z_NULL, 0);
902 crc = crc32(crc, (const unsigned char*) &md5tr, sizeof(md5tr));
903 if (crc == md5trcrc) {
904 if (write(adb_control_twrp_fd, &md5tr, sizeof(md5tr)) < 1) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500905 std::string msg = "Cannot write to adb_control_twrp_fd: ";
906 printErrMsg(msg, errno);
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400907 close_restore_fds();
908 return false;
909 }
910 }
911 else {
912 adblogwrite("ADB MD5TRAILER crc header doesn't match\n");
913 close_restore_fds();
914 return false;
915 }
916
917 AdbBackupFileTrailer md5;
918
919 memset(&md5, 0, sizeof(md5));
920 strncpy(md5.start_of_trailer, TWRP, sizeof(md5.start_of_trailer));
921 strncpy(md5.type, TWMD5, sizeof(md5.type));
922 std::string md5string = digest->return_digest_string();
923 strncpy(md5.md5, md5string.c_str(), sizeof(md5.md5));
924
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500925 adblogwrite("sending MD5 verification: " + md5string + "\n");
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400926 if (write(adb_control_twrp_fd, &md5, sizeof(md5)) < 1) {
bigbiff bigbiff38b83c12017-12-28 19:58:52 -0500927 std::string msg = "Cannot write to adb_control_twrp_fd: ";
928 printErrMsg(msg, errno);
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400929 close_restore_fds();
930 return false;
931 }
932 return true;
933 }
934 return false;
935}