blob: 39803b0ce661edc3326915d75be3c103d310eed6 [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>
21#include <string.h>
22#include <fcntl.h>
23#include <errno.h>
24#include <zlib.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <sys/select.h>
28#include <sys/time.h>
29#include <string>
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040030#include <vector>
bigbiffce8f83c2015-12-12 18:30:21 -050031#include <fstream>
32#include <sstream>
Ethan Yonkerfefe5912017-09-30 22:22:13 -050033#include <assert.h>
bigbiffce8f83c2015-12-12 18:30:21 -050034
35#include "twadbstream.h"
36#include "libtwadbbu.hpp"
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -040037#include "twrpback.hpp"
bigbiffce8f83c2015-12-12 18:30:21 -050038
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040039bool twadbbu::Check_ADB_Backup_File(std::string fname) {
40 struct AdbBackupStreamHeader adbbuhdr;
41 uint32_t crc, adbbuhdrcrc;
42 unsigned char buf[MAX_ADB_READ];
43 int bytes;
44
45 int fd = open(fname.c_str(), O_RDONLY);
46 if (fd < 0) {
47 printf("Unable to open %s for reading: %s.\n", fname.c_str(), strerror(errno));
48 close(fd);
49 return false;
50 }
51 bytes = read(fd, &buf, sizeof(buf));
52 close(fd);
53
Ethan Yonkerfefe5912017-09-30 22:22:13 -050054 if (memcpy(&adbbuhdr, buf, sizeof(adbbuhdr)) == NULL) {
55 printf("Unable to memcpy: %s (%s).\n", fname.c_str(), strerror(errno));
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040056 return false;
57 }
58 adbbuhdrcrc = adbbuhdr.crc;
59 memset(&adbbuhdr.crc, 0, sizeof(adbbuhdr.crc));
60 crc = crc32(0L, Z_NULL, 0);
61 crc = crc32(crc, (const unsigned char*) &adbbuhdr, sizeof(adbbuhdr));
62
63 return (crc == adbbuhdrcrc);
64}
65
66std::vector<std::string> twadbbu::Get_ADB_Backup_Files(std::string fname) {
67 unsigned char buf[MAX_ADB_READ];
68 struct AdbBackupControlType structcmd;
69 std::vector<std::string> adb_partitions;
70
71 int fd = open(fname.c_str(), O_RDONLY);
72 if (fd < 0) {
73 printf("Unable to open %s for reading: %s\n", fname.c_str(), strerror(errno));
74 close(fd);
75 return std::vector<std::string>();
76 }
77
bigbiff bigbiff38b83c12017-12-28 19:58:52 -050078 while (true) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040079 std::string cmdstr;
80 int readbytes;
Ethan Yonkerfefe5912017-09-30 22:22:13 -050081 if ((readbytes = read(fd, &buf, sizeof(buf))) > 0) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -040082 memcpy(&structcmd, buf, sizeof(structcmd));
83 assert(structcmd.type == TWENDADB || structcmd.type == TWIMG || structcmd.type == TWFN);
84 cmdstr = structcmd.type;
85 std::string cmdtype = cmdstr.substr(0, sizeof(structcmd.type) - 1);
86 if (cmdtype == TWENDADB) {
87 struct AdbBackupControlType endadb;
88 uint32_t crc, endadbcrc;
89
90 memcpy(&endadb, buf, sizeof(endadb));
91 endadbcrc = endadb.crc;
92 memset(&endadb.crc, 0, sizeof(endadb.crc));
93 crc = crc32(0L, Z_NULL, 0);
94 crc = crc32(crc, (const unsigned char*) &endadb, sizeof(endadb));
95
96 if (crc == endadbcrc) {
97 break;
98 }
99 else {
100 printf("ADB TWENDADB crc header doesn't match\n");
101 close(fd);
102 return std::vector<std::string>();
103 }
104 }
105 else if (cmdtype == TWIMG || cmdtype == TWFN) {
106 struct twfilehdr twfilehdr;
107 uint32_t crc, twfilehdrcrc;
108
109 memcpy(&twfilehdr, buf, sizeof(twfilehdr));
110 twfilehdrcrc = twfilehdr.crc;
111 memset(&twfilehdr.crc, 0, sizeof(twfilehdr.crc));
112
113 crc = crc32(0L, Z_NULL, 0);
114 crc = crc32(crc, (const unsigned char*) &twfilehdr, sizeof(twfilehdr));
115 if (crc == twfilehdrcrc) {
116 std::string adbfile = twfilehdr.name;
117 int pos = adbfile.find_last_of("/") + 1;
118 adbfile = adbfile.substr(pos, adbfile.size());
119 adb_partitions.push_back(adbfile);
120 }
121 else {
122 printf("ADB crc header doesn't match\n");
123 close(fd);
124 return std::vector<std::string>();
125 }
126 }
127 }
128 }
129 close(fd);
130 return adb_partitions;
131}
132
bigbiffce8f83c2015-12-12 18:30:21 -0500133bool twadbbu::Write_ADB_Stream_Header(uint64_t partition_count) {
134 struct AdbBackupStreamHeader twhdr;
135 int adb_control_bu_fd;
136
137 memset(&twhdr, 0, sizeof(twhdr));
138 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
139 if (adb_control_bu_fd < 0) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400140 printf("Cannot write to TW_ADB_BU_CONTROL: %s\n", strerror(errno));
bigbiffce8f83c2015-12-12 18:30:21 -0500141 return false;
142 }
143
144 strncpy(twhdr.start_of_header, TWRP, sizeof(twhdr.start_of_header));
145 strncpy(twhdr.type, TWSTREAMHDR, sizeof(twhdr.type));
146 twhdr.partition_count = partition_count;
147 twhdr.version = ADB_BACKUP_VERSION;
148 memset(twhdr.space, 0, sizeof(twhdr.space));
149 twhdr.crc = crc32(0L, Z_NULL, 0);
150 twhdr.crc = crc32(twhdr.crc, (const unsigned char*) &twhdr, sizeof(twhdr));
151 if (write(adb_control_bu_fd, &twhdr, sizeof(twhdr)) < 0) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400152 printf("Cannot write to adb control channel: %s\n", strerror(errno));
bigbiffce8f83c2015-12-12 18:30:21 -0500153 close(adb_control_bu_fd);
154 return false;
155 }
156 return true;
157}
158
159bool twadbbu::Write_ADB_Stream_Trailer() {
160 int adb_control_bu_fd;
161 struct AdbBackupControlType endadb;
162
163 memset(&endadb, 0, sizeof(endadb));
164
165 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY);
166 if (adb_control_bu_fd < 0) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400167 printf("Error opening adb_control_bu_fd: %s\n", strerror(errno));
bigbiffce8f83c2015-12-12 18:30:21 -0500168 return false;
169 }
170 strncpy(endadb.start_of_header, TWRP, sizeof(endadb.start_of_header));
171 strncpy(endadb.type, TWENDADB, sizeof(endadb.type));
172 endadb.crc = crc32(0L, Z_NULL, 0);
173 endadb.crc = crc32(endadb.crc, (const unsigned char*) &endadb, sizeof(endadb));
174 if (write(adb_control_bu_fd, &endadb, sizeof(endadb)) < 0) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400175 printf("Cannot write to ADB control: %s\n", strerror(errno));
bigbiffce8f83c2015-12-12 18:30:21 -0500176 close(adb_control_bu_fd);
177 return false;
178 }
179 close(adb_control_bu_fd);
180 return true;
181}
182
183bool twadbbu::Write_TWFN(std::string Backup_FileName, uint64_t file_size, bool use_compression) {
184 int adb_control_bu_fd;
185 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
186 struct twfilehdr twfilehdr;
187 strncpy(twfilehdr.start_of_header, TWRP, sizeof(twfilehdr.start_of_header));
188 strncpy(twfilehdr.type, TWFN, sizeof(twfilehdr.type));
189 strncpy(twfilehdr.name, Backup_FileName.c_str(), sizeof(twfilehdr.name));
190 twfilehdr.size = (file_size == 0 ? 1024 : file_size);
191 twfilehdr.compressed = use_compression;
192 twfilehdr.crc = crc32(0L, Z_NULL, 0);
193 twfilehdr.crc = crc32(twfilehdr.crc, (const unsigned char*) &twfilehdr, sizeof(twfilehdr));
194
195 printf("Sending TWFN to adb\n");
196 if (write(adb_control_bu_fd, &twfilehdr, sizeof(twfilehdr)) < 1) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400197 printf("Cannot that write to adb_control_bu_fd: %s\n", strerror(errno));
bigbiffce8f83c2015-12-12 18:30:21 -0500198 close(adb_control_bu_fd);
199 return false;
200 }
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400201 fsync(adb_control_bu_fd);
bigbiffce8f83c2015-12-12 18:30:21 -0500202 close(adb_control_bu_fd);
203 return true;
204}
205
206bool twadbbu::Write_TWIMG(std::string Backup_FileName, uint64_t file_size) {
207 int adb_control_bu_fd;
208 struct twfilehdr twimghdr;
209
210 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
211 strncpy(twimghdr.start_of_header, TWRP, sizeof(twimghdr.start_of_header));
212 strncpy(twimghdr.type, TWIMG, sizeof(twimghdr.type));
213 twimghdr.size = file_size;
214 strncpy(twimghdr.name, Backup_FileName.c_str(), sizeof(twimghdr.name));
215 twimghdr.crc = crc32(0L, Z_NULL, 0);
216 twimghdr.crc = crc32(twimghdr.crc, (const unsigned char*) &twimghdr, sizeof(twimghdr));
217 printf("Sending TWIMG to adb\n");
218 if (write(adb_control_bu_fd, &twimghdr, sizeof(twimghdr)) < 1) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400219 printf("Cannot write to adb control channel: %s\n", strerror(errno));
bigbiffce8f83c2015-12-12 18:30:21 -0500220 return false;
221 }
222
223 return true;
224}
225
226bool twadbbu::Write_TWEOF() {
227 struct AdbBackupControlType tweof;
228 int adb_control_bu_fd;
229 int errctr = 0;
230
231 printf("opening TW_ADB_BU_CONTROL\n");
232 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
233 while (adb_control_bu_fd < 0) {
234 printf("failed to open TW_ADB_BU_CONTROL. Retrying: %s\n", strerror(errno));
235 adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
236 usleep(10000);
237 errctr++;
238 if (errctr > ADB_BU_MAX_ERROR) {
239 printf("Cannot write to adb_control_bu_fd: %s.\n", strerror(errno));
240 close(adb_control_bu_fd);
241 return false;
242 }
243 }
244 memset(&tweof, 0, sizeof(tweof));
245 strncpy(tweof.start_of_header, TWRP, sizeof(tweof.start_of_header));
246 strncpy(tweof.type, TWEOF, sizeof(tweof.type));
247 tweof.crc = crc32(0L, Z_NULL, 0);
248 tweof.crc = crc32(tweof.crc, (const unsigned char*) &tweof, sizeof(tweof));
249 printf("Sending TWEOF to adb backup\n");
250 if (write(adb_control_bu_fd, &tweof, sizeof(tweof)) < 0) {
251 printf("Cannot write to adb_control_bu_fd: %s.\n", strerror(errno));
252 close(adb_control_bu_fd);
253 return false;
254 }
255 close(adb_control_bu_fd);
256 return true;
257}
258
259bool twadbbu::Write_TWERROR() {
260 struct AdbBackupControlType twerror;
261 int adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
262
263 strncpy(twerror.start_of_header, TWRP, sizeof(twerror.start_of_header));
264 strncpy(twerror.type, TWERROR, sizeof(twerror.type));
265 memset(twerror.space, 0, sizeof(twerror.space));
266 twerror.crc = crc32(0L, Z_NULL, 0);
267 twerror.crc = crc32(twerror.crc, (const unsigned char*) &twerror, sizeof(twerror));
268 if (write(adb_control_bu_fd, &twerror, sizeof(twerror)) < 0) {
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -0400269 printf("Cannot write to adb control channel: %s\n", strerror(errno));
bigbiffce8f83c2015-12-12 18:30:21 -0500270 return false;
271 }
272 close(adb_control_bu_fd);
273 return true;
274}
275
276bool twadbbu::Write_TWENDADB() {
277 struct AdbBackupControlType endadb;
278 int adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
279
280 memset(&endadb, 0, sizeof(endadb));
281 strncpy(endadb.start_of_header, TWRP, sizeof(endadb.start_of_header));
282 strncpy(endadb.type, TWENDADB, sizeof(endadb.type));
283 endadb.crc = crc32(0L, Z_NULL, 0);
284 endadb.crc = crc32(endadb.crc, (const unsigned char*) &endadb, sizeof(endadb));
285
286 printf("Sending TWENDADB to ADB Backup\n");
287 if (write(adb_control_bu_fd, &endadb, sizeof(endadb)) < 1) {
288 printf("Cannot write to ADB_CONTROL_BU_FD: %s\n", strerror(errno));
289 return false;
290 }
291
292 close(adb_control_bu_fd);
293 return true;
294}
bigbiff bigbiffadcb4d82017-09-25 10:51:56 -0400295
296bool twadbbu::Write_TWDATA(FILE* adbd_fp) {
297 struct AdbBackupControlType data_block;
298 memset(&data_block, 0, sizeof(data_block));
299 strncpy(data_block.start_of_header, TWRP, sizeof(data_block.start_of_header));
300 strncpy(data_block.type, TWDATA, sizeof(data_block.type));
301 data_block.crc = crc32(0L, Z_NULL, 0);
302 data_block.crc = crc32(data_block.crc, (const unsigned char*) &data_block, sizeof(data_block));
303 if (fwrite(&data_block, 1, sizeof(data_block), adbd_fp) != sizeof(data_block)) {
304 return false;
305 }
306 return true;
307}