Add twrpTar binary

Change-Id: I9db1aac350cd2ca02cceccc249ebd2f0b3c3c671
diff --git a/Android.mk b/Android.mk
index 4ab358a..c6c7f3c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -353,7 +353,8 @@
     $(commands_recovery_local_path)/minuitwrp/Android.mk \
     $(commands_recovery_local_path)/openaes/Android.mk \
     $(commands_recovery_local_path)/toolbox/Android.mk \
-    $(commands_recovery_local_path)/libmincrypt/Android.mk
+    $(commands_recovery_local_path)/libmincrypt/Android.mk \
+    $(commands_recovery_local_path)/twrpTarMain/Android.mk
 
 ifeq ($(TW_INCLUDE_CRYPTO_SAMSUNG), true)
     include $(commands_recovery_local_path)/crypto/libcrypt_samsung/Android.mk
diff --git a/libtar/append.c b/libtar/append.c
index dcd8649..514cf54 100644
--- a/libtar/append.c
+++ b/libtar/append.c
@@ -27,6 +27,9 @@
 # include <unistd.h>
 #endif
 
+#ifdef HAVE_SELINUX
+#include "selinux/selinux.h"
+#endif
 
 struct tar_dev
 {
diff --git a/twcommon.h b/twcommon.h
index 2c96d04..69cc7e6 100644
--- a/twcommon.h
+++ b/twcommon.h
@@ -5,9 +5,15 @@
 extern "C" {
 #endif
 
+#ifndef BUILD_TWRPTAR_MAIN
 #include "gui/gui.h"
 #define LOGERR(...) gui_print("E:" __VA_ARGS__)
 #define LOGINFO(...) fprintf(stdout, "I:" __VA_ARGS__)
+#else
+#define LOGERR(...) printf("E:" __VA_ARGS__)
+#define LOGINFO(...) printf("I:" __VA_ARGS__)
+#define gui_print(...) printf( __VA_ARGS__ )
+#endif
 
 #define STRINGIFY(x) #x
 #define EXPAND(x) STRINGIFY(x)
diff --git a/twrpTarMain/Android.mk b/twrpTarMain/Android.mk
new file mode 100644
index 0000000..5cd6fe1
--- /dev/null
+++ b/twrpTarMain/Android.mk
@@ -0,0 +1,71 @@
+LOCAL_PATH:= $(call my-dir)
+
+# Build static binary
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	twrpTarMain.cpp \
+	../twrp-functions.cpp \
+	../twrpTar.cpp \
+	../tarWrite.c \
+	../twrpDU.cpp
+LOCAL_CFLAGS:= -g -c -W -DBUILD_TWRPTAR_MAIN
+
+LOCAL_C_INCLUDES += bionic external/stlport/stlport
+LOCAL_STATIC_LIBRARIES := libc libtar_static libstlport_static libstdc++
+
+ifeq ($(TWHAVE_SELINUX), true)
+    LOCAL_C_INCLUDES += external/libselinux/include
+    LOCAL_STATIC_LIBRARIES += libselinux
+    LOCAL_CFLAGS += -DHAVE_SELINUX -g
+endif
+ifneq ($(RECOVERY_SDCARD_ON_DATA),)
+	LOCAL_CFLAGS += -DRECOVERY_SDCARD_ON_DATA
+endif
+ifeq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true)
+    LOCAL_CFLAGS += -DTW_EXCLUDE_ENCRYPTED_BACKUPS
+else
+	LOCAL_STATIC_LIBRARIES += libopenaes_static
+endif
+
+LOCAL_MODULE:= twrpTar_static
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_MODULE_TAGS:= eng
+LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
+include $(BUILD_EXECUTABLE)
+
+
+# Build shared binary
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	twrpTarMain.cpp \
+	../twrp-functions.cpp \
+	../twrpTar.cpp \
+	../tarWrite.c \
+	../twrpDU.cpp
+LOCAL_CFLAGS:= -g -c -W -DBUILD_TWRPTAR_MAIN
+
+LOCAL_C_INCLUDES += bionic external/stlport/stlport
+LOCAL_SHARED_LIBRARIES := libc libtar libstlport libstdc++
+
+ifeq ($(TWHAVE_SELINUX), true)
+    LOCAL_C_INCLUDES += external/libselinux/include
+    LOCAL_SHARED_LIBRARIES += libselinux
+    LOCAL_CFLAGS += -DHAVE_SELINUX -g
+endif
+ifneq ($(RECOVERY_SDCARD_ON_DATA),)
+	LOCAL_CFLAGS += -DRECOVERY_SDCARD_ON_DATA
+endif
+ifeq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true)
+    LOCAL_CFLAGS += -DTW_EXCLUDE_ENCRYPTED_BACKUPS
+else
+	LOCAL_SHARED_LIBRARIES += libopenaes
+endif
+
+LOCAL_MODULE:= twrpTar
+LOCAL_MODULE_TAGS:= eng
+LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
+include $(BUILD_EXECUTABLE)
diff --git a/twrpTarMain/twrpTarMain.cpp b/twrpTarMain/twrpTarMain.cpp
new file mode 100644
index 0000000..ef6a5ef
--- /dev/null
+++ b/twrpTarMain/twrpTarMain.cpp
@@ -0,0 +1,164 @@
+
+/*
+	Copyright 2014 TeamWin
+	This file is part of TWRP/TeamWin Recovery Project.
+
+	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 "../twrp-functions.hpp"
+#include "../twrpTar.hpp"
+#include "../twrpDU.hpp"
+#include <string.h>
+
+twrpDU du;
+
+void usage() {
+	printf("twrpTar <action> [options]\n\n");
+	printf("actions: -c create\n");
+	printf("         -x extract\n\n");
+	printf(" -d    target directory\n");
+	printf(" -t    output file\n");
+	printf(" -m    skip media subfolder (has data media)\n");
+	printf(" -z    compress backup (/sbin/pigz must be present)\n");
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+	printf(" -e    encrypt/decrypt backup followed by password (/sbin/openaes must be present)\n");
+	printf(" -u    encrypt using userdata encryption (must be used with -e\n");
+#endif
+	printf("\n\n");
+	printf("Example: twrpTar -c -d /cache -t /sdcard/test.tar\n");
+	printf("         twrpTar -x -d /cache -t /sdcard/test.tar\n");
+}
+
+int main(int argc, char **argv) {
+	twrpTar tar;
+	int use_encryption = 0, userdata_encryption = 0, has_data_media = 0, use_compression = 0, include_root = 0;
+	int i, action = 0;
+	unsigned j;
+	string Directory, Tar_Filename;
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+	string Password;
+#endif
+
+	if (argc < 2) {
+		usage();
+		return 0;
+	}
+
+	if (strcmp(argv[1], "-c") == 0)
+		action = 1; // create tar
+	else if (strcmp(argv[1], "-x") == 0)
+		action = 2; // extract tar
+	else {
+		printf("Invalid action '%s' specified.\n", argv[1]);
+		usage();
+		return -1;
+	}
+
+	for (i = 2; i < argc; i++) {
+		if (strcmp(argv[i], "-d") == 0) {
+			i++;
+			if (argc <= i) {
+				printf("No argument specified for %s\n", argv[i - 1]);
+				usage();
+				return -1;
+			} else {
+				Directory = argv[i];
+			}
+		} else if (strcmp(argv[i], "-t") == 0) {
+			i++;
+			if (argc <= i) {
+				printf("No argument specified for %s\n", argv[i - 1]);
+				usage();
+				return -1;
+			} else {
+				Tar_Filename = argv[i];
+			}
+		} else if (strcmp(argv[i], "-e") == 0) {
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+			i++;
+			if (argc <= i) {
+				printf("No argument specified for %s\n", argv[i - 1]);
+				usage();
+				return -1;
+			} else {
+				use_encryption = 1;
+				Password = argv[i];
+			}
+#else
+			printf("Encrypted tar file support not present\n");
+			usage();
+			return -1;
+#endif
+		} else if (strcmp(argv[i], "-m") == 0) {
+			if (action == 2)
+				printf("NOTE: %s option not needed when extracting.\n", argv[i]);
+			has_data_media = 1;
+		} else if (strcmp(argv[i], "-z") == 0) {
+			if (action == 2)
+				printf("NOTE: %s option not needed when extracting.\n", argv[i]);
+			use_compression = 1;
+		} else if (strcmp(argv[i], "-u") == 0) {
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+			if (action == 2)
+				printf("NOTE: %s option not needed when extracting.\n", argv[i]);
+			userdata_encryption = 1;
+#else
+			printf("Encrypted tar file support not present\n");
+			usage();
+			return -1;
+#endif
+		}
+	}
+
+	vector<string> excludedirs = du.get_absolute_dirs();
+	for (j = 0; j < excludedirs.size(); ++j) {
+		tar.setexcl(excludedirs.at(j));
+	}
+	tar.has_data_media = has_data_media;
+	tar.setdir(Directory);
+	tar.setfn(Tar_Filename);
+	tar.setsize(du.Get_Folder_Size(Directory));
+	tar.use_compression = use_compression;
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+	if (userdata_encryption && !use_encryption) {
+		printf("userdata encryption set without encryption option\n");
+		usage();
+		return -1;
+	}
+	if (use_encryption) {
+		tar.use_encryption = use_encryption;
+		tar.userdata_encryption = userdata_encryption;
+		tar.setpassword(Password);
+	} else {
+		use_encryption = false;
+	}
+#endif
+	if (action == 1) {
+		if (tar.createTarFork() != 0) {
+			sync();
+			return -1;
+		}
+		sync();
+		printf("\n\ntar created successfully.\n");
+	} else if (action == 2) {
+		if (tar.extractTarFork() != 0) {
+			sync();
+			return -1;
+		}
+		sync();
+		printf("\n\ntar extracted successfully.\n");
+	}
+	return 0;
+}