bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 1 | /* |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 2 | Copyright 2013 to 2017 TeamWin |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 3 | 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> |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 21 | #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> |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 31 | #include <sstream> |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 32 | #include <fstream> |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 33 | #include <algorithm> |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 34 | #include <utils/threads.h> |
| 35 | #include <pthread.h> |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 36 | |
| 37 | #include "twadbstream.h" |
| 38 | #include "twrpback.hpp" |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 39 | #include "libtwadbbu.hpp" |
bigbiff bigbiff | 56cf564 | 2016-08-19 17:43:45 -0400 | [diff] [blame] | 40 | #include "../twrpDigest/twrpDigest.hpp" |
| 41 | #include "../twrpDigest/twrpMD5.hpp" |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 42 | #include "../twrpAdbBuFifo.hpp" |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 43 | |
| 44 | twrpback::twrpback(void) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 45 | adbd_fp = NULL; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 46 | 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; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 52 | ors_fd = 0; |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 53 | debug_adb_fd = 0; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 54 | firstPart = true; |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 55 | createFifos(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 56 | adbloginit(); |
| 57 | } |
| 58 | |
| 59 | twrpback::~twrpback(void) { |
| 60 | adblogfile.close(); |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 61 | closeFifos(); |
| 62 | } |
| 63 | |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 64 | void twrpback::printErrMsg(std::string msg, int errNum) { |
| 65 | std::stringstream str; |
| 66 | str << strerror(errNum); |
| 67 | adblogwrite(msg + " " + str.str() + "\n"); |
| 68 | } |
| 69 | |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 70 | void twrpback::createFifos(void) { |
| 71 | if (mkfifo(TW_ADB_BU_CONTROL, 0666) < 0) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 72 | std::string msg = "Unable to create TW_ADB_BU_CONTROL fifo: "; |
| 73 | printErrMsg(msg, errno); |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 74 | } |
| 75 | if (mkfifo(TW_ADB_TWRP_CONTROL, 0666) < 0) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 76 | std::string msg = "Unable to create TW_ADB_TWRP_CONTROL fifo: "; |
| 77 | printErrMsg(msg, errno); |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 78 | unlink(TW_ADB_BU_CONTROL); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | void twrpback::closeFifos(void) { |
| 83 | if (unlink(TW_ADB_BU_CONTROL) < 0) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 84 | std::string msg = "Unable to remove TW_ADB_BU_CONTROL: "; |
| 85 | printErrMsg(msg, errno); |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 86 | } |
| 87 | if (unlink(TW_ADB_TWRP_CONTROL) < 0) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 88 | std::string msg = "Unable to remove TW_ADB_TWRP_CONTROL: "; |
| 89 | printErrMsg(msg, errno); |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 90 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 91 | } |
| 92 | |
| 93 | void twrpback::adbloginit(void) { |
| 94 | adblogfile.open("/tmp/adb.log", std::fstream::app); |
| 95 | } |
| 96 | |
| 97 | void twrpback::adblogwrite(std::string writemsg) { |
| 98 | adblogfile << writemsg << std::flush; |
| 99 | } |
| 100 | |
| 101 | void 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 110 | #ifdef _DEBUG_ADB_BACKUP |
| 111 | if (debug_adb_fd > 0) |
| 112 | close(debug_adb_fd); |
| 113 | #endif |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 114 | if (adbd_fp != NULL) |
| 115 | fclose(adbd_fp); |
| 116 | if (access(TW_ADB_BACKUP, F_OK) == 0) |
| 117 | unlink(TW_ADB_BACKUP); |
| 118 | } |
| 119 | |
| 120 | void 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 133 | #ifdef _DEBUG_ADB_BACKUP |
| 134 | if (debug_adb_fd > 0) |
| 135 | close(debug_adb_fd); |
| 136 | #endif |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 137 | } |
| 138 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 139 | bool twrpback::backup(std::string command) { |
bigbiff bigbiff | 56cf564 | 2016-08-19 17:43:45 -0400 | [diff] [blame] | 140 | twrpMD5 digest; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 141 | int bytes = 0, errctr = 0; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 142 | char adbReadStream[MAX_ADB_READ]; |
| 143 | uint64_t totalbytes = 0, dataChunkBytes = 0, fileBytes = 0; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 144 | uint64_t md5fnsize = 0; |
| 145 | struct AdbBackupControlType endadb; |
| 146 | |
Ethan Yonker | 58f2132 | 2018-08-24 11:17:36 -0500 | [diff] [blame] | 147 | //ADBSTRUCT_STATIC_ASSERT(sizeof(endadb) == MAX_ADB_READ); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 148 | |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 156 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | if (mkfifo(TW_ADB_BACKUP, 0666) < 0) { |
| 160 | adblogwrite("Unable to create TW_ADB_BACKUP fifo\n"); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 161 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 162 | } |
| 163 | |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 164 | adblogwrite("opening TW_ADB_FIFO\n"); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 165 | |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 166 | write_fd = open(TW_ADB_FIFO, O_WRONLY); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 167 | while (write_fd < 0) { |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 168 | write_fd = open(TW_ADB_FIFO, O_WRONLY); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 169 | usleep(10000); |
| 170 | errctr++; |
| 171 | if (errctr > ADB_BU_MAX_ERROR) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 172 | std::string msg = "Unable to open TW_ADB_FIFO"; |
| 173 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 174 | close_backup_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 175 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 176 | } |
| 177 | } |
| 178 | |
Ayke van Laethem | 05c2de4 | 2017-06-02 00:19:27 +0200 | [diff] [blame] | 179 | memset(operation, 0, sizeof(operation)); |
Ethan Yonker | 58f2132 | 2018-08-24 11:17:36 -0500 | [diff] [blame] | 180 | if (snprintf(operation, sizeof(operation), "adbbackup %s", command.c_str()) >= (int)sizeof(operation)) { |
Ayke van Laethem | 05c2de4 | 2017-06-02 00:19:27 +0200 | [diff] [blame] | 181 | adblogwrite("Operation too big to write to ORS_INPUT_FILE\n"); |
| 182 | close_backup_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 183 | return false; |
Ayke van Laethem | 05c2de4 | 2017-06-02 00:19:27 +0200 | [diff] [blame] | 184 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 185 | if (write(write_fd, operation, sizeof(operation)) != sizeof(operation)) { |
| 186 | adblogwrite("Unable to write to ORS_INPUT_FILE\n"); |
| 187 | close_backup_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 188 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 189 | } |
| 190 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 191 | memset(&adbReadStream, 0, sizeof(adbReadStream)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 192 | 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 199 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 200 | } |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 207 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 208 | } |
| 209 | |
| 210 | //loop until TWENDADB sent |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 211 | while (true) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 212 | if (read(adb_control_bu_fd, &cmd, sizeof(cmd)) > 0) { |
| 213 | struct AdbBackupControlType structcmd; |
| 214 | |
| 215 | memcpy(&structcmd, cmd, sizeof(cmd)); |
Ayke van Laethem | 05c2de4 | 2017-06-02 00:19:27 +0200 | [diff] [blame] | 216 | std::string cmdtype = structcmd.get_type(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 217 | |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 223 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 224 | } |
| 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 Mower | cc19c6f | 2017-02-22 11:31:35 -0600 | [diff] [blame] | 230 | std::stringstream str; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 231 | str << totalbytes; |
| 232 | adblogwrite(str.str() + " total bytes written\n"); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 233 | break; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 234 | } |
| 235 | //we recieved the TWSTREAMHDR structure metadata to write to adb |
| 236 | else if (cmdtype == TWSTREAMHDR) { |
| 237 | writedata = false; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 238 | adblogwrite("writing TWSTREAMHDR\n"); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 239 | if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 240 | std::string msg = "Error writing TWSTREAMHDR to adbd"; |
| 241 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 242 | close_backup_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 243 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 244 | } |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 251 | adblogwrite("writing TWIMG\n"); |
bigbiff bigbiff | 56cf564 | 2016-08-19 17:43:45 -0400 | [diff] [blame] | 252 | digest.init(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 253 | memset(&twimghdr, 0, sizeof(twimghdr)); |
| 254 | memcpy(&twimghdr, cmd, sizeof(cmd)); |
| 255 | md5fnsize = twimghdr.size; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 256 | compressed = false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 257 | |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 258 | #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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 266 | if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 267 | adblogwrite("Error writing TWIMG to adbd\n"); |
| 268 | close_backup_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 269 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 270 | } |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 278 | adblogwrite("writing TWFN\n"); |
bigbiff bigbiff | 56cf564 | 2016-08-19 17:43:45 -0400 | [diff] [blame] | 279 | digest.init(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 280 | |
Ethan Yonker | 58f2132 | 2018-08-24 11:17:36 -0500 | [diff] [blame] | 281 | //ADBSTRUCT_STATIC_ASSERT(sizeof(twfilehdr) == MAX_ADB_READ); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 282 | |
| 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 289 | #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 | |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 297 | if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { |
| 298 | adblogwrite("Error writing TWFN to adbd\n"); |
| 299 | close_backup_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 300 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 301 | } |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 315 | while ((bytes = read(adb_read_fd, &adbReadStream, sizeof(adbReadStream)) != 0)) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 316 | totalbytes += bytes; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 317 | 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 325 | std::string msg = "Cannot write to adbd stream: "; |
| 326 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 327 | } |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 328 | #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 |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 336 | fflush(adbd_fp); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 337 | delete [] writeAdbReadStream; |
| 338 | memset(adbReadStream, 0, sizeof(adbReadStream)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 339 | } |
| 340 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 341 | if (fileBytes % DATA_MAX_CHUNK_SIZE != 0) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 342 | int64_t count = fileBytes / DATA_MAX_CHUNK_SIZE + 1; |
| 343 | uint64_t ceilingBytes = count * DATA_MAX_CHUNK_SIZE; |
| 344 | char padding[ceilingBytes - fileBytes]; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 345 | int paddingBytes = sizeof(padding); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 346 | memset(padding, 0, paddingBytes); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 347 | std::stringstream paddingStr; |
| 348 | paddingStr << paddingBytes; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 349 | adblogwrite("writing padding to stream: " + paddingStr.str() + " bytes\n"); |
| 350 | if (fwrite(padding, 1, paddingBytes, adbd_fp) != sizeof(padding)) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 351 | adblogwrite("Error writing padding to adbd\n"); |
| 352 | close_backup_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 353 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 354 | } |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 355 | #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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 363 | totalbytes += paddingBytes; |
| 364 | digest.update((unsigned char *) padding, paddingBytes); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 365 | fflush(adbd_fp); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 366 | } |
| 367 | |
| 368 | AdbBackupFileTrailer md5trailer; |
| 369 | |
| 370 | memset(&md5trailer, 0, sizeof(md5trailer)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 371 | |
bigbiff bigbiff | 56cf564 | 2016-08-19 17:43:45 -0400 | [diff] [blame] | 372 | std::string md5string = digest.return_digest_string(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 373 | |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 388 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 389 | } |
| 390 | fflush(adbd_fp); |
| 391 | writedata = false; |
| 392 | firstDataPacket = true; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 393 | fileBytes = 0; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 394 | } |
| 395 | memset(&cmd, 0, sizeof(cmd)); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 396 | dataChunkBytes = 0; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 397 | } |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 403 | while ((bytes = read(adb_read_fd, &adbReadStream, sizeof(adbReadStream))) > 0) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 404 | if (firstDataPacket) { |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 405 | if (!twadbbu::Write_TWDATA(adbd_fp)) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 406 | close_backup_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 407 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 408 | } |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 409 | fileBytes += MAX_ADB_READ; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 410 | fflush(adbd_fp); |
| 411 | firstDataPacket = false; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 412 | dataChunkBytes += sizeof(adbReadStream); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 413 | } |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 414 | char *writeAdbReadStream = new char [bytes]; |
| 415 | memcpy(writeAdbReadStream, adbReadStream, bytes); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 416 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 417 | digest.update((unsigned char *) writeAdbReadStream, bytes); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 418 | |
| 419 | totalbytes += bytes; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 420 | fileBytes += bytes; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 421 | dataChunkBytes += bytes; |
| 422 | |
Ethan Yonker | 58f2132 | 2018-08-24 11:17:36 -0500 | [diff] [blame] | 423 | if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) != (unsigned long long)bytes) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 424 | adblogwrite("Error writing backup data to adbd\n"); |
| 425 | close_backup_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 426 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 427 | } |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 428 | #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 |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 436 | fflush(adbd_fp); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 437 | delete [] writeAdbReadStream; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 438 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 439 | memset(&adbReadStream, 0, sizeof(adbReadStream)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 440 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 441 | 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 462 | std::string msg = "Cannot write to adbd stream: "; |
| 463 | printErrMsg(msg, errno); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 464 | close_restore_fds(); |
| 465 | return false; |
| 466 | } |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 467 | #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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 475 | fflush(adbd_fp); |
| 476 | delete [] writeAdbReadStream; |
| 477 | } |
| 478 | memset(&extraData, 0, bytesLeft); |
| 479 | if (bytesLeft == 0) { |
| 480 | break; |
| 481 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 482 | } |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 483 | |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 484 | fflush(adbd_fp); |
| 485 | dataChunkBytes = 0; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 486 | firstDataPacket = true; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 487 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 488 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 489 | } |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 496 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 497 | } |
| 498 | fflush(adbd_fp); |
| 499 | close_backup_fds(); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 500 | return true; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 501 | } |
| 502 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 503 | bool twrpback::restore(void) { |
bigbiff bigbiff | 56cf564 | 2016-08-19 17:43:45 -0400 | [diff] [blame] | 504 | twrpMD5 digest; |
| 505 | char cmd[MAX_ADB_READ]; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 506 | char readAdbStream[MAX_ADB_READ]; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 507 | struct AdbBackupControlType structcmd; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 508 | int errctr = 0; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 509 | uint64_t totalbytes = 0, dataChunkBytes = 0; |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 510 | uint64_t md5fnsize = 0, fileBytes = 0; |
Ethan Yonker | 58f2132 | 2018-08-24 11:17:36 -0500 | [diff] [blame] | 511 | bool read_from_adb; |
| 512 | bool md5sumdata; |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 513 | bool compressed, tweofrcvd, extraData; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 514 | |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 515 | read_from_adb = true; |
| 516 | |
| 517 | signal(SIGPIPE, SIG_IGN); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 518 | signal(SIGHUP, SIG_IGN); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 519 | |
| 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 524 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 525 | } |
| 526 | |
| 527 | if(mkfifo(TW_ADB_RESTORE, 0666)) { |
| 528 | adblogwrite("Unable to create TW_ADB_RESTORE fifo\n"); |
| 529 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 530 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 531 | } |
| 532 | |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 533 | adblogwrite("opening TW_ADB_FIFO\n"); |
| 534 | write_fd = open(TW_ADB_FIFO, O_WRONLY); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 535 | |
| 536 | while (write_fd < 0) { |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 537 | write_fd = open(TW_ADB_FIFO, O_WRONLY); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 538 | errctr++; |
| 539 | if (errctr > ADB_BU_MAX_ERROR) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 540 | std::string msg = "Unable to open TW_ADB_FIFO."; |
| 541 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 542 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 543 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 544 | } |
| 545 | } |
| 546 | |
Ayke van Laethem | 05c2de4 | 2017-06-02 00:19:27 +0200 | [diff] [blame] | 547 | memset(operation, 0, sizeof(operation)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 548 | sprintf(operation, "adbrestore"); |
| 549 | if (write(write_fd, operation, sizeof(operation)) != sizeof(operation)) { |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 550 | adblogwrite("Unable to write to TW_ADB_FIFO\n"); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 551 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 552 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 553 | } |
| 554 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 555 | memset(&readAdbStream, 0, sizeof(readAdbStream)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 556 | 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 561 | std::string msg = "Unable to open TW_ADB_BU_CONTROL for writing."; |
| 562 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 563 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 564 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 565 | } |
| 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 570 | std::string msg = "Unable to open TW_ADB_TWRP_CONTROL for writing. Retrying..."; |
| 571 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 572 | 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 579 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 580 | } |
| 581 | } |
| 582 | } |
| 583 | |
| 584 | //Loop until we receive TWENDADB from TWRP |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 585 | while (true) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 586 | 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 Laethem | 05c2de4 | 2017-06-02 00:19:27 +0200 | [diff] [blame] | 590 | std::string cmdtype = structcmd.get_type(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 591 | |
| 592 | //If we receive TWEOF from TWRP close adb data fifo |
| 593 | if (cmdtype == TWEOF) { |
| 594 | adblogwrite("Received TWEOF\n"); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 595 | read_from_adb = true; |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 596 | tweofrcvd = true; |
| 597 | close(adb_write_fd); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 598 | } |
| 599 | //Break when TWRP sends TWENDADB |
| 600 | else if (cmdtype == TWENDADB) { |
| 601 | adblogwrite("Received TWENDADB\n"); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 602 | break; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 603 | } |
| 604 | //we received an error, exit and unlink |
| 605 | else if (cmdtype == TWERROR) { |
| 606 | adblogwrite("Error received. Quitting...\n"); |
| 607 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 608 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 609 | } |
| 610 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 611 | //If we should read from the adb stream, write commands and data to TWRP |
| 612 | if (read_from_adb) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 613 | int readbytes; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 614 | if ((readbytes = fread(readAdbStream, 1, sizeof(readAdbStream), adbd_fp)) == sizeof(readAdbStream)) { |
| 615 | memcpy(&structcmd, readAdbStream, sizeof(readAdbStream)); |
Ayke van Laethem | 05c2de4 | 2017-06-02 00:19:27 +0200 | [diff] [blame] | 616 | std::string cmdtype = structcmd.get_type(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 617 | |
| 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 623 | md5sumdata = false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 624 | memset(&endadb, 0, sizeof(endadb)); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 625 | memcpy(&endadb, readAdbStream, sizeof(readAdbStream)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 626 | 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 632 | adblogwrite("sending TWENDADB\n"); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 633 | if (write(adb_control_twrp_fd, &endadb, sizeof(endadb)) < 1) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 634 | std::string msg = "Cannot write to ADB_CONTROL_READ_FD: "; |
| 635 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 636 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 637 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 638 | } |
bigbiff bigbiff | b5ecaad | 2017-03-20 18:53:53 -0400 | [diff] [blame] | 639 | read_from_adb = false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 640 | } |
| 641 | else { |
| 642 | adblogwrite("ADB TWENDADB crc header doesn't match\n"); |
| 643 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 644 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 645 | } |
| 646 | } |
| 647 | //Send TWRP partition metadata |
| 648 | else if (cmdtype == TWSTREAMHDR) { |
| 649 | struct AdbBackupStreamHeader cnthdr; |
| 650 | uint32_t crc, cnthdrcrc; |
| 651 | |
Ethan Yonker | 58f2132 | 2018-08-24 11:17:36 -0500 | [diff] [blame] | 652 | //ADBSTRUCT_STATIC_ASSERT(sizeof(cnthdr) == MAX_ADB_READ); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 653 | |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 654 | md5sumdata = false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 655 | memset(&cnthdr, 0, sizeof(cnthdr)); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 656 | memcpy(&cnthdr, readAdbStream, sizeof(readAdbStream)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 657 | 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 664 | if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 0) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 665 | std::string msg = "Cannot write to adb_control_twrp_fd: "; |
| 666 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 667 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 668 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 669 | } |
| 670 | } |
| 671 | else { |
| 672 | adblogwrite("ADB TWSTREAMHDR crc header doesn't match\n"); |
| 673 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 674 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 675 | } |
| 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 681 | md5sumdata = false; |
| 682 | fileBytes = 0; |
| 683 | read_from_adb = true; |
| 684 | dataChunkBytes = 0; |
| 685 | extraData = false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 686 | |
bigbiff bigbiff | 56cf564 | 2016-08-19 17:43:45 -0400 | [diff] [blame] | 687 | digest.init(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 688 | adblogwrite("Restoring TWIMG\n"); |
| 689 | memset(&twimghdr, 0, sizeof(twimghdr)); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 690 | memcpy(&twimghdr, readAdbStream, sizeof(readAdbStream)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 691 | 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 698 | if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 699 | std::string msg = "Cannot write to adb_control_twrp_fd: "; |
| 700 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 701 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 702 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 703 | } |
| 704 | } |
| 705 | else { |
| 706 | adblogwrite("ADB TWIMG crc header doesn't match\n"); |
| 707 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 708 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 709 | } |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 710 | |
| 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 | |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 720 | 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 727 | fileBytes = 0; |
| 728 | md5sumdata = false; |
| 729 | read_from_adb = true; |
| 730 | dataChunkBytes = 0; |
| 731 | extraData = false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 732 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 733 | digest.init(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 734 | adblogwrite("Restoring TWFN\n"); |
| 735 | memset(&twfilehdr, 0, sizeof(twfilehdr)); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 736 | memcpy(&twfilehdr, readAdbStream, sizeof(readAdbStream)); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 737 | 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 745 | if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 746 | std::string msg = "Cannot write to adb_control_twrp_fd: "; |
| 747 | printErrMsg(msg, errno); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 748 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 749 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 750 | } |
| 751 | } |
| 752 | else { |
| 753 | adblogwrite("ADB TWFN crc header doesn't match\n"); |
| 754 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 755 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 756 | } |
| 757 | |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 758 | #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; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 768 | adblogwrite("opening TW_ADB_RESTORE\n"); |
| 769 | adb_write_fd = open(TW_ADB_RESTORE, O_WRONLY); |
| 770 | } |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 771 | else if (cmdtype == MD5TRAILER) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 772 | 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 781 | if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) { |
| 782 | close_restore_fds(); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 783 | break; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 784 | } |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 785 | continue; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 786 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 787 | //Send the tar or partition image md5 to TWRP |
| 788 | else if (cmdtype == TWDATA) { |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 789 | dataChunkBytes += sizeof(readAdbStream); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 790 | while (true) { |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 791 | if ((readbytes = fread(readAdbStream, 1, sizeof(readAdbStream), adbd_fp)) != sizeof(readAdbStream)) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 792 | close_restore_fds(); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 793 | return false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 794 | } |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 795 | memcpy(&structcmd, readAdbStream, sizeof(readAdbStream)); |
Ayke van Laethem | 05c2de4 | 2017-06-02 00:19:27 +0200 | [diff] [blame] | 796 | std::string cmdtype = structcmd.get_type(); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 797 | |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 798 | dataChunkBytes += readbytes; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 799 | totalbytes += readbytes; |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 800 | fileBytes += readbytes; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 801 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 802 | if (cmdtype == MD5TRAILER) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 803 | 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 811 | if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) { |
| 812 | close_restore_fds(); |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 813 | break; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 814 | } |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 815 | break; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 816 | } |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 817 | |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 818 | 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 bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 830 | |
| 831 | if (write(adb_write_fd, readAdbStream, sizeof(readAdbStream)) < 0) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 832 | std::string msg = "Cannot write to TWRP ADB FIFO: "; |
| 833 | md5sumdata = true; |
| 834 | printErrMsg(msg, errno); |
| 835 | adblogwrite("end of stream reached.\n"); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 836 | break; |
| 837 | } |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 838 | |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 839 | if (dataChunkBytes == DATA_MAX_CHUNK_SIZE) { |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 840 | dataChunkBytes = 0; |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 841 | md5sumdata = false; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 842 | break; |
| 843 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 844 | } |
| 845 | } |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 846 | else if (md5sumdata) { |
| 847 | digest.update((unsigned char*)readAdbStream, sizeof(readAdbStream)); |
| 848 | md5sumdata = true; |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 849 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 850 | } |
| 851 | } |
| 852 | } |
Matt Mower | cc19c6f | 2017-02-22 11:31:35 -0600 | [diff] [blame] | 853 | std::stringstream str; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 854 | str << totalbytes; |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 855 | close_restore_fds(); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 856 | adblogwrite(str.str() + " bytes restored from adbbackup\n"); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 857 | return true; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 858 | } |
| 859 | |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 860 | void twrpback::streamFileForTWRP(void) { |
| 861 | adblogwrite("streamFileForTwrp" + streamFn + "\n"); |
| 862 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 863 | |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 864 | void 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; |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 871 | } |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 872 | restore(); |
| 873 | } |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 874 | |
bigbiff bigbiff | 19fb79c | 2016-09-05 21:04:51 -0400 | [diff] [blame] | 875 | void 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); |
bigbiff | ce8f83c | 2015-12-12 18:30:21 -0500 | [diff] [blame] | 881 | } |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 882 | |
| 883 | bool twrpback::checkMD5Trailer(char readAdbStream[], uint64_t md5fnsize, twrpMD5 *digest) { |
| 884 | struct AdbBackupFileTrailer md5tr; |
| 885 | uint32_t crc, md5trcrc, md5ident, md5identmatch; |
| 886 | |
Ethan Yonker | 58f2132 | 2018-08-24 11:17:36 -0500 | [diff] [blame] | 887 | //ADBSTRUCT_STATIC_ASSERT(sizeof(md5tr) == MAX_ADB_READ); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 888 | 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 905 | std::string msg = "Cannot write to adb_control_twrp_fd: "; |
| 906 | printErrMsg(msg, errno); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 907 | 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 bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 925 | adblogwrite("sending MD5 verification: " + md5string + "\n"); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 926 | if (write(adb_control_twrp_fd, &md5, sizeof(md5)) < 1) { |
bigbiff bigbiff | 38b83c1 | 2017-12-28 19:58:52 -0500 | [diff] [blame] | 927 | std::string msg = "Cannot write to adb_control_twrp_fd: "; |
| 928 | printErrMsg(msg, errno); |
bigbiff bigbiff | adcb4d8 | 2017-09-25 10:51:56 -0400 | [diff] [blame] | 929 | close_restore_fds(); |
| 930 | return false; |
| 931 | } |
| 932 | return true; |
| 933 | } |
| 934 | return false; |
| 935 | } |