Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19fb79c7 authored by bigbiff bigbiff's avatar bigbiff bigbiff Committed by Ethan Yonker
Browse files

ADB Backup: add ability for TWRP GUI to restore

Restore adb backup files that TWRP made to your PC.
Put files in your backup directory to see them.

e.g. /sdcard/TWRP/BACKUPS/<sn>

Change-Id: I2c57970d77b64c39a302159041456e761c185259
parent 372019c8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -61,7 +61,8 @@ LOCAL_SRC_FILES := \
    twrp-functions.cpp \
    twrpDigestDriver.cpp \
    openrecoveryscript.cpp \
    tarWrite.c
    tarWrite.c \
    twrpAdbBuFifo.cpp

ifneq ($(TARGET_RECOVERY_REBOOT_SRC),)
  LOCAL_SRC_FILES += $(TARGET_RECOVERY_REBOOT_SRC)
+27 −20
Original line number Diff line number Diff line
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libtwadbbu
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS = -fno-strict-aliasing -D_LARGFILE_SOURCE
LOCAL_C_INCLUDES += bionic external/zlib
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 23; echo $$?),0)
    LOCAL_C_INCLUDES += external/stlport/stlport
endif

LOCAL_SRC_FILES:= \
LOCAL_SRC_FILES = \
        libtwadbbu.cpp \
        twrpback.cpp

LOCAL_SHARED_LIBRARIES += libstdc++ libz libtwrpdigest
LOCAL_SHARED_LIBRARIES += libz libc libstdc++ libtwrpdigest

ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 23; echo $$?),0)
    LOCAL_C_INCLUDES += external/stlport/stlport
    LOCAL_SHARED_LIBRARIES += libstlport
else
    LOCAL_SHARED_LIBRARIES += libc++
endif

LOCAL_C_INCLUDES += bionic external/zlib
LOCAL_CFLAGS:= -c -W
LOCAL_MODULE:= twrpbu
LOCAL_MODULE_STEM := bu
LOCAL_MODULE_TAGS:= eng
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
include $(BUILD_EXECUTABLE)
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libtwadbbu
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS = -D_FILE_OFFSET_BITS=64 -fno-strict-aliasing
LOCAL_C_INCLUDES += bionic external/zlib

LOCAL_SRC_FILES:= \
        adbbumain.cpp

LOCAL_SHARED_LIBRARIES += libstdc++ libz libtwadbbu

ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 23; echo $$?),0)
    LOCAL_C_INCLUDES += external/stlport/stlport
    LOCAL_SHARED_LIBRARIES += libstlport
@@ -33,9 +37,12 @@ else
    LOCAL_SHARED_LIBRARIES += libc++
endif

LOCAL_SRC_FILES = \
    libtwadbbu.cpp

LOCAL_SHARED_LIBRARIES += libz libc libstdc++
LOCAL_C_INCLUDES += bionic external/zlib
LOCAL_CFLAGS:= -c -W
LOCAL_MODULE:= twrpbu
LOCAL_MODULE_STEM := bu
LOCAL_MODULE_TAGS:= eng
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
include $(BUILD_EXECUTABLE)
include $(BUILD_SHARED_LIBRARY)

adbbu/adbbumain.cpp

0 → 100644
+89 −0
Original line number Diff line number Diff line
/*
		Copyright 2013 to 2017 TeamWin
		TWRP is free software: you can redistribute it and/or modify
		it under the terms of the GNU General Public License as published by
		the Free Software Foundation, either version 3 of the License, or
		(at your option) any later version.

		TWRP is distributed in the hope that it will be useful,
		but WITHOUT ANY WARRANTY; without even the implied warranty of
		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
		GNU General Public License for more details.

		You should have received a copy of the GNU General Public License
		along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <string>
#include <sstream>

#include "twrpback.hpp"
#include "twadbstream.h"


int main(int argc, char **argv) {
	int index;
	int ret = 0, pos = 0;
	int maxpos = sizeof(TWRPARG + 2);
	std::string command;
	twrpback tw;

	tw.adblogwrite("Starting adb backup and restore\n");
	command = argv[1];
	for (index = 2; index < argc; index++) {
		command = command + " " + argv[index];
	}

	pos = command.find(TWRP_BACKUP_ARG);
	if (pos < 0 || pos > (maxpos + sizeof(TWRP_BACKUP_ARG) + 1)) {
		pos = command.find(TWRP_RESTORE_ARG);
	}
	if (pos < 0 || pos > maxpos + sizeof(TWRP_STREAM_ARG + 1)) {
		pos = command.find(TWRP_STREAM_ARG);
	}

	tw.adblogwrite("command: " + command + "\n");
	command.erase(0, pos);
	command.erase(std::remove(command.begin(), command.end(), '\''), command.end());

	if (command.substr(0, sizeof(TWRP_BACKUP_ARG) - 1) == TWRP_BACKUP_ARG) {
		tw.adblogwrite("Starting adb backup\n");
		if (isdigit(*argv[1]))
			tw.adbd_fd = atoi(argv[1]);
		else
			tw.adbd_fd = 1;
		ret = tw.backup(command);
	}
	else if (command.substr(0, sizeof(TWRP_RESTORE_ARG) - 1) == TWRP_RESTORE_ARG) {
		tw.adblogwrite("Starting adb restore\n");
		if (isdigit(*argv[1]))
			tw.adbd_fd = atoi(argv[1]);
		else
			tw.adbd_fd = 0;
		ret = tw.restore();
	}
	else if (command.substr(0, sizeof(TWRP_STREAM_ARG) - 1) == TWRP_STREAM_ARG) {
		tw.setStreamFileName(argv[3]);
		tw.threadStream();
	}
	if (ret == 0)
		tw.adblogwrite("Adb backup/restore completed\n");
	else
		tw.adblogwrite("Adb backup/restore failed\n");

	if (unlink(TW_ADB_BU_CONTROL) < 0) {
		std::stringstream str;
		str << strerror(errno);
		tw.adblogwrite("Unable to remove TW_ADB_BU_CONTROL: " + str.str());
	}
	unlink(TW_ADB_TWRP_CONTROL);
	return ret;
}
+104 −8
Original line number Diff line number Diff line
/*
		Copyright 2013 to 2016 TeamWin
		Copyright 2013 to 2017 TeamWin
		TWRP is free software: you can redistribute it and/or modify
		it under the terms of the GNU General Public License as published by
		the Free Software Foundation, either version 3 of the License, or
@@ -27,12 +27,107 @@
#include <sys/select.h>
#include <sys/time.h>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>

#include "twadbstream.h"
#include "libtwadbbu.hpp"

bool twadbbu::Check_ADB_Backup_File(std::string fname) {
	struct AdbBackupStreamHeader adbbuhdr;
	uint32_t crc, adbbuhdrcrc;
	unsigned char buf[MAX_ADB_READ];
	int bytes;

	int fd = open(fname.c_str(), O_RDONLY);
	if (fd < 0) {
		printf("Unable to open %s for reading: %s.\n", fname.c_str(), strerror(errno));
		close(fd);
		return false;
	}
	bytes = read(fd, &buf, sizeof(buf));
	close(fd);

	if (memcpy(&adbbuhdr, buf, sizeof(adbbuhdr)) < 0) {
		printf("Unable to memcpy: %s.\n", fname.c_str(), strerror(errno));
		return false;
	}
	adbbuhdrcrc = adbbuhdr.crc;
	memset(&adbbuhdr.crc, 0, sizeof(adbbuhdr.crc));
	crc = crc32(0L, Z_NULL, 0);
	crc = crc32(crc, (const unsigned char*) &adbbuhdr, sizeof(adbbuhdr));

	return (crc == adbbuhdrcrc);
}

std::vector<std::string> twadbbu::Get_ADB_Backup_Files(std::string fname) {
	unsigned char buf[MAX_ADB_READ];
	struct AdbBackupControlType structcmd;
	std::vector<std::string> adb_partitions;

	int fd = open(fname.c_str(), O_RDONLY);
	if (fd < 0) {
		printf("Unable to open %s for reading: %s\n", fname.c_str(), strerror(errno));
		close(fd);
		return std::vector<std::string>();
	}

	while (1) {
		std::string cmdstr;
		int readbytes;
		if (readbytes = read(fd, &buf, sizeof(buf)) > 0) {
			memcpy(&structcmd, buf, sizeof(structcmd));
			assert(structcmd.type == TWENDADB || structcmd.type == TWIMG || structcmd.type == TWFN);
			cmdstr = structcmd.type;
			std::string cmdtype = cmdstr.substr(0, sizeof(structcmd.type) - 1);
			if (cmdtype == TWENDADB) {
				struct AdbBackupControlType endadb;
				uint32_t crc, endadbcrc;

				memcpy(&endadb, buf, sizeof(endadb));
				endadbcrc = endadb.crc;
				memset(&endadb.crc, 0, sizeof(endadb.crc));
				crc = crc32(0L, Z_NULL, 0);
				crc = crc32(crc, (const unsigned char*) &endadb, sizeof(endadb));

				if (crc == endadbcrc) {
					break;
				}
				else {
					printf("ADB TWENDADB crc header doesn't match\n");
					close(fd);
					return std::vector<std::string>();
				}
			}
			else if (cmdtype == TWIMG || cmdtype == TWFN) {
				struct twfilehdr twfilehdr;
				uint32_t crc, twfilehdrcrc;

				memcpy(&twfilehdr, buf, sizeof(twfilehdr));
				twfilehdrcrc = twfilehdr.crc;
				memset(&twfilehdr.crc, 0, sizeof(twfilehdr.crc));

				crc = crc32(0L, Z_NULL, 0);
				crc = crc32(crc, (const unsigned char*) &twfilehdr, sizeof(twfilehdr));
				if (crc == twfilehdrcrc) {
					std::string adbfile = twfilehdr.name;
					int pos = adbfile.find_last_of("/") + 1;
					adbfile = adbfile.substr(pos, adbfile.size());
					adb_partitions.push_back(adbfile);
				}
				else {
					printf("ADB crc header doesn't match\n");
					close(fd);
					return std::vector<std::string>();
				}
			}
		}
	}
	close(fd);
	return adb_partitions;
}

bool twadbbu::Write_ADB_Stream_Header(uint64_t partition_count) {
	struct AdbBackupStreamHeader twhdr;
	int adb_control_bu_fd;
@@ -40,7 +135,7 @@ bool twadbbu::Write_ADB_Stream_Header(uint64_t partition_count) {
	memset(&twhdr, 0, sizeof(twhdr));
	adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
	if (adb_control_bu_fd < 0) {
		printf("Cannot write to TW_ADB_BU_CONTROL.\n");
		printf("Cannot write to TW_ADB_BU_CONTROL: %s\n", strerror(errno));
		return false;
	}

@@ -52,7 +147,7 @@ bool twadbbu::Write_ADB_Stream_Header(uint64_t partition_count) {
	twhdr.crc = crc32(0L, Z_NULL, 0);
	twhdr.crc = crc32(twhdr.crc, (const unsigned char*) &twhdr, sizeof(twhdr));
	if (write(adb_control_bu_fd, &twhdr, sizeof(twhdr)) < 0) {
		printf("Cannot write to adb control channel\n");
		printf("Cannot write to adb control channel: %s\n", strerror(errno));
		close(adb_control_bu_fd);
		return false;
	}
@@ -67,7 +162,7 @@ bool twadbbu::Write_ADB_Stream_Trailer() {

	adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY);
	if (adb_control_bu_fd < 0) {
		printf("Error opening adb_control_bu_fd\n");
		printf("Error opening adb_control_bu_fd: %s\n", strerror(errno));
		return false;
	}
	strncpy(endadb.start_of_header, TWRP, sizeof(endadb.start_of_header));
@@ -75,7 +170,7 @@ bool twadbbu::Write_ADB_Stream_Trailer() {
	endadb.crc = crc32(0L, Z_NULL, 0);
	endadb.crc = crc32(endadb.crc, (const unsigned char*) &endadb, sizeof(endadb));
	if (write(adb_control_bu_fd, &endadb, sizeof(endadb)) < 0) {
		printf("Cannot write to ADB control.\n");
		printf("Cannot write to ADB control: %s\n", strerror(errno));
		close(adb_control_bu_fd);
		return false;
	}
@@ -97,10 +192,11 @@ bool twadbbu::Write_TWFN(std::string Backup_FileName, uint64_t file_size, bool u

	printf("Sending TWFN to adb\n");
	if (write(adb_control_bu_fd, &twfilehdr, sizeof(twfilehdr)) < 1) {
		printf("Cannot that write to adb_control_bu_fd\n");
		printf("Cannot that write to adb_control_bu_fd: %s\n", strerror(errno));
		close(adb_control_bu_fd);
		return false;
	}
	fsync(adb_control_bu_fd);
	close(adb_control_bu_fd);
	return true;
}
@@ -118,7 +214,7 @@ bool twadbbu::Write_TWIMG(std::string Backup_FileName, uint64_t file_size) {
	twimghdr.crc = crc32(twimghdr.crc, (const unsigned char*) &twimghdr, sizeof(twimghdr));
	printf("Sending TWIMG to adb\n");
	if (write(adb_control_bu_fd, &twimghdr, sizeof(twimghdr)) < 1) {
		printf("Cannot write to adb control channel\n");
		printf("Cannot write to adb control channel: %s\n", strerror(errno));
		return false;
	}

@@ -168,7 +264,7 @@ bool twadbbu::Write_TWERROR() {
	twerror.crc = crc32(0L, Z_NULL, 0);
	twerror.crc = crc32(twerror.crc, (const unsigned char*) &twerror, sizeof(twerror));
	if (write(adb_control_bu_fd, &twerror, sizeof(twerror)) < 0) {
		printf("Cannot write to adb control channel");
		printf("Cannot write to adb control channel: %s\n", strerror(errno));
		return false;
	}
	close(adb_control_bu_fd);
+8 −1
Original line number Diff line number Diff line
/*
		Copyright 2013 to 2016 TeamWin
		Copyright 2013 to 2017 TeamWin
		TWRP is free software: you can redistribute it and/or modify
		it under the terms of the GNU General Public License as published by
		the Free Software Foundation, either version 3 of the License, or
@@ -13,6 +13,8 @@
		You should have received a copy of the GNU General Public License
		along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIBTWADBBU_HPP
#define _LIBTWADBBU_HPP

#include <stdio.h>
#include <stdlib.h>
@@ -26,6 +28,7 @@
#include <sys/select.h>
#include <sys/time.h>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>

@@ -34,6 +37,8 @@

class twadbbu {
public:
	static bool Check_ADB_Backup_File(std::string fname);                                          //Check if file is ADB Backup file
	static std::vector<std::string> Get_ADB_Backup_Files(std::string fname);                       //List ADB Files in String Vector
	static bool Write_ADB_Stream_Header(uint64_t partition_count);                                 //Write ADB Stream Header to stream
	static bool Write_ADB_Stream_Trailer();                                                        //Write ADB Stream Trailer to stream
	static bool Write_TWFN(std::string Backup_FileName, uint64_t file_size, bool use_compression); //Write a tar image to stream
@@ -42,3 +47,5 @@ public:
	static bool Write_TWERROR();                                                                   //Write error message occurred to stream
	static bool Write_TWENDADB();                                                                  //Write ADB End-Of-Stream command to stream
};

#endif //__LIBTWADBBU_HPP
Loading