summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk3
-rw-r--r--libtar/Android.mk20
-rw-r--r--libtar/append.c3
-rw-r--r--openaes/Android.mk13
-rw-r--r--openrecoveryscript.cpp4
-rw-r--r--partition.cpp61
-rwxr-xr-xprebuilt/install-recovery.sh10
-rwxr-xr-xprebuilt/subin112164 -> 113036 bytes
-rw-r--r--twcommon.h6
-rw-r--r--twrp-functions.cpp426
-rw-r--r--twrp-functions.hpp21
-rw-r--r--twrpTar.cpp55
-rw-r--r--twrpTar.hpp3
-rw-r--r--twrpTarMain/Android.mk71
-rw-r--r--twrpTarMain/twrpTarMain.cpp164
15 files changed, 549 insertions, 311 deletions
diff --git a/Android.mk b/Android.mk
index 4ab358a9d..c6c7f3c40 100644
--- a/Android.mk
+++ b/Android.mk
@@ -353,7 +353,8 @@ include $(commands_recovery_local_path)/injecttwrp/Android.mk \
$(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/Android.mk b/libtar/Android.mk
index f936e96ff..1972573bb 100644
--- a/libtar/Android.mk
+++ b/libtar/Android.mk
@@ -1,5 +1,6 @@
LOCAL_PATH := $(call my-dir)
+# Build shared library
include $(CLEAR_VARS)
LOCAL_MODULE := libtar
@@ -19,3 +20,22 @@ endif
include $(BUILD_SHARED_LIBRARY)
+# Build static library
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libtar_static
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULES_TAGS = optional
+LOCAL_CFLAGS =
+LOCAL_SRC_FILES = append.c block.c decode.c encode.c extract.c handle.c output.c util.c wrapper.c basename.c strmode.c libtar_hash.c libtar_list.c dirname.c
+LOCAL_C_INCLUDES += $(LOCAL_PATH) \
+ external/zlib
+LOCAL_STATIC_LIBRARIES += libz libc
+
+ifeq ($(TWHAVE_SELINUX), true)
+ LOCAL_C_INCLUDES += external/libselinux/include
+ LOCAL_STATIC_LIBRARIES += libselinux
+ LOCAL_CFLAGS += -DHAVE_SELINUX
+endif
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/libtar/append.c b/libtar/append.c
index dcd864984..514cf54bb 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/openaes/Android.mk b/openaes/Android.mk
index 1beefdac4..360cf6ccc 100644
--- a/openaes/Android.mk
+++ b/openaes/Android.mk
@@ -2,6 +2,7 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
ifneq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true)
+ # Build shared binary
LOCAL_SRC_FILES:= src/oaes.c \
LOCAL_C_INCLUDES := \
bootable/recovery/openaes/src/isaac \
@@ -14,6 +15,7 @@ ifneq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true)
LOCAL_SHARED_LIBRARIES = libopenaes libc
include $(BUILD_EXECUTABLE)
+ # Build shared library
include $(CLEAR_VARS)
LOCAL_MODULE := libopenaes
LOCAL_MODULE_TAGS := eng
@@ -23,4 +25,15 @@ ifneq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true)
LOCAL_SRC_FILES = src/oaes_lib.c src/isaac/rand.c
LOCAL_SHARED_LIBRARIES = libc
include $(BUILD_SHARED_LIBRARY)
+
+ # Build static library
+ include $(CLEAR_VARS)
+ LOCAL_MODULE := libopenaes_static
+ LOCAL_MODULE_TAGS := eng
+ LOCAL_C_INCLUDES := \
+ bootable/recovery/openaes/src/isaac \
+ bootable/recovery/openaes/inc
+ LOCAL_SRC_FILES = src/oaes_lib.c src/isaac/rand.c
+ LOCAL_STATIC_LIBRARIES = libc
+ include $(BUILD_STATIC_LIBRARY)
endif
diff --git a/openrecoveryscript.cpp b/openrecoveryscript.cpp
index bede6d7c2..4479ec919 100644
--- a/openrecoveryscript.cpp
+++ b/openrecoveryscript.cpp
@@ -349,6 +349,10 @@ int OpenRecoveryScript::run_script_file(void) {
sideload = 1; // Causes device to go to the home screen afterwards
gui_print("Sideload finished.\n");
}
+ } else if (strcmp(command, "fixperms") == 0 || strcmp(command, "fixpermissions") == 0) {
+ ret_val = PartitionManager.Fix_Permissions();
+ if (ret_val != 0)
+ ret_val = 1; // failure
} else {
LOGERR("Unrecognized script command: '%s'\n", command);
ret_val = 1;
diff --git a/partition.cpp b/partition.cpp
index 3f19b7d61..74271922f 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -53,6 +53,7 @@ extern "C" {
}
#ifdef HAVE_SELINUX
#include "selinux/selinux.h"
+#include <selinux/label.h>
#endif
using namespace std;
@@ -1344,17 +1345,25 @@ bool TWPartition::Wipe_EXT4() {
return false;
#if defined(HAVE_SELINUX) && defined(USE_EXT4)
+ int ret;
+ char *secontext = NULL;
+
gui_print("Formatting %s using make_ext4fs function.\n", Display_Name.c_str());
- if (make_ext4fs(Actual_Block_Device.c_str(), Length, Mount_Point.c_str(), selinux_handle) != 0) {
+
+ if (selabel_lookup(selinux_handle, &secontext, Mount_Point.c_str(), S_IFDIR) < 0) {
+ LOGINFO("Cannot lookup security context for '%s'\n", Mount_Point.c_str());
+ ret = make_ext4fs(Actual_Block_Device.c_str(), Length, Mount_Point.c_str(), NULL);
+ } else {
+ ret = make_ext4fs(Actual_Block_Device.c_str(), Length, Mount_Point.c_str(), selinux_handle);
+ }
+ if (ret != 0) {
LOGERR("Unable to wipe '%s' using function call.\n", Mount_Point.c_str());
return false;
} else {
- #ifdef HAVE_SELINUX
string sedir = Mount_Point + "/lost+found";
PartitionManager.Mount_By_Path(sedir.c_str(), true);
rmdir(sedir.c_str());
mkdir(sedir.c_str(), S_IRWXU | S_IRWXG | S_IWGRP | S_IXGRP);
- #endif
return true;
}
#else
@@ -1584,6 +1593,9 @@ bool TWPartition::Backup_Tar(string backup_folder) {
tar.use_encryption = use_encryption;
if (Use_Userdata_Encryption)
tar.userdata_encryption = use_encryption;
+ string Password;
+ DataManager::GetValue("tw_backup_password", Password);
+ tar.setpassword(Password);
} else {
use_encryption = false;
}
@@ -1672,37 +1684,18 @@ bool TWPartition::Restore_Tar(string restore_folder, string Restore_File_System)
return false;
Full_FileName = restore_folder + "/" + Backup_FileName;
- /*if (!TWFunc::Path_Exists(Full_FileName)) {
- if (!TWFunc::Path_Exists(Full_FileName)) {
- // Backup is multiple archives
- LOGINFO("Backup is multiple archives.\n");
- sprintf(split_index, "%03i", index);
- Full_FileName = restore_folder + "/" + Backup_FileName + split_index;
- while (TWFunc::Path_Exists(Full_FileName)) {
- index++;
- gui_print("Restoring archive %i...\n", index);
- LOGINFO("Restoring '%s'...\n", Full_FileName.c_str());
- twrpTar tar;
- tar.setdir("/");
- tar.setfn(Full_FileName);
- if (tar.extractTarFork() != 0)
- return false;
- sprintf(split_index, "%03i", index);
- Full_FileName = restore_folder + "/" + Backup_FileName + split_index;
- }
- if (index == 0) {
- LOGERR("Error locating restore file: '%s'\n", Full_FileName.c_str());
- return false;
- }
- }
- } else {*/
- twrpTar tar;
- tar.setdir(Backup_Path);
- tar.setfn(Full_FileName);
- tar.backup_name = Backup_Name;
- if (tar.extractTarFork() != 0)
- return false;
- //}
+ twrpTar tar;
+ tar.setdir(Backup_Path);
+ tar.setfn(Full_FileName);
+ tar.backup_name = Backup_Name;
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+ string Password;
+ DataManager::GetValue("tw_restore_password", Password);
+ if (!Password.empty())
+ tar.setpassword(Password);
+#endif
+ if (tar.extractTarFork() != 0)
+ return false;
return true;
}
diff --git a/prebuilt/install-recovery.sh b/prebuilt/install-recovery.sh
index 9b4374520..f62cf0b96 100755
--- a/prebuilt/install-recovery.sh
+++ b/prebuilt/install-recovery.sh
@@ -5,15 +5,13 @@
# to launch it from init.rc
# Launches SuperSU in daemon mode only on Android 4.3+.
-# Nothing will happen on 4.2.x or older.
+# Nothing will happen on 4.2.x or older, unless SELinux+Enforcing.
# If you want to force loading the daemon, use "--daemon" instead
/system/xbin/daemonsu --auto-daemon &
-# Some apps like to run stuff from this script as well, but the
-# installer will have done "chattr +i" on this file to prevent
-# accidental modification and deletion. In your code, just search
-# this file for "install-recovery-2.sh", and if present, write
-# there instead.
+# Some apps like to run stuff from this script as well, that will
+# obviously break root - in your code, just search this file
+# for "install-recovery-2.sh", and if present, write there instead.
/system/etc/install-recovery-2.sh
diff --git a/prebuilt/su b/prebuilt/su
index da77f0a70..941542798 100755
--- a/prebuilt/su
+++ b/prebuilt/su
Binary files differ
diff --git a/twcommon.h b/twcommon.h
index 2c96d04e2..69cc7e676 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/twrp-functions.cpp b/twrp-functions.cpp
index df7174362..5145b2678 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -18,7 +18,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
+#include <string>
#include <unistd.h>
#include <vector>
#include <dirent.h>
@@ -32,18 +32,20 @@
#include <sys/vfs.h>
#include <sys/types.h>
#include <sys/wait.h>
-#ifdef ANDROID_RB_POWEROFF
- #include "cutils/android_reboot.h"
-#endif
#include <iostream>
#include <fstream>
#include <sstream>
#include "twrp-functions.hpp"
-#include "partitions.hpp"
#include "twcommon.h"
+#ifndef BUILD_TWRPTAR_MAIN
#include "data.hpp"
+#include "partitions.hpp"
#include "variables.h"
#include "bootloader.h"
+#ifdef ANDROID_RB_POWEROFF
+ #include "cutils/android_reboot.h"
+#endif
+#endif // ndef BUILD_TWRPTAR_MAIN
#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
#include "openaes/inc/oaes_lib.h"
#endif
@@ -115,6 +117,165 @@ string TWFunc::Get_Path(string Path) {
return Path;
}
+int TWFunc::Wait_For_Child(pid_t pid, int *status, string Child_Name) {
+ pid_t rc_pid;
+
+ rc_pid = waitpid(pid, status, 0);
+ if (rc_pid > 0) {
+ if (WEXITSTATUS(*status) == 0)
+ LOGINFO("%s process ended with RC=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Success
+ else if (WIFSIGNALED(*status)) {
+ LOGINFO("%s process ended with signal: %d\n", Child_Name.c_str(), WTERMSIG(*status)); // Seg fault or some other non-graceful termination
+ return -1;
+ } else if (WEXITSTATUS(*status) != 0) {
+ LOGINFO("%s process ended with ERROR=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Graceful exit, but there was an error
+ return -1;
+ }
+ } else { // no PID returned
+ if (errno == ECHILD)
+ LOGINFO("%s no child process exist\n", Child_Name.c_str());
+ else {
+ LOGINFO("%s Unexpected error\n", Child_Name.c_str());
+ return -1;
+ }
+ }
+ return 0;
+}
+
+bool TWFunc::Path_Exists(string Path) {
+ // Check to see if the Path exists
+ struct stat st;
+ if (stat(Path.c_str(), &st) != 0)
+ return false;
+ else
+ return true;
+}
+
+int TWFunc::Get_File_Type(string fn) {
+ string::size_type i = 0;
+ int firstbyte = 0, secondbyte = 0;
+ char header[3];
+
+ ifstream f;
+ f.open(fn.c_str(), ios::in | ios::binary);
+ f.get(header, 3);
+ f.close();
+ firstbyte = header[i] & 0xff;
+ secondbyte = header[++i] & 0xff;
+
+ if (firstbyte == 0x1f && secondbyte == 0x8b)
+ return 1; // Compressed
+ else if (firstbyte == 0x4f && secondbyte == 0x41)
+ return 2; // Encrypted
+ else
+ return 0; // Unknown
+
+ return 0;
+}
+
+int TWFunc::Try_Decrypting_File(string fn, string password) {
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+ OAES_CTX * ctx = NULL;
+ uint8_t _key_data[32] = "";
+ FILE *f;
+ uint8_t buffer[4096];
+ uint8_t *buffer_out = NULL;
+ uint8_t *ptr = NULL;
+ size_t read_len = 0, out_len = 0;
+ int firstbyte = 0, secondbyte = 0, key_len;
+ size_t _j = 0;
+ size_t _key_data_len = 0;
+
+ // mostly kanged from OpenAES oaes.c
+ for( _j = 0; _j < 32; _j++ )
+ _key_data[_j] = _j + 1;
+ _key_data_len = password.size();
+ if( 16 >= _key_data_len )
+ _key_data_len = 16;
+ else if( 24 >= _key_data_len )
+ _key_data_len = 24;
+ else
+ _key_data_len = 32;
+ memcpy(_key_data, password.c_str(), password.size());
+
+ ctx = oaes_alloc();
+ if (ctx == NULL) {
+ LOGERR("Failed to allocate OAES\n");
+ return -1;
+ }
+
+ oaes_key_import_data(ctx, _key_data, _key_data_len);
+
+ f = fopen(fn.c_str(), "rb");
+ if (f == NULL) {
+ LOGERR("Failed to open '%s' to try decrypt\n", fn.c_str());
+ return -1;
+ }
+ read_len = fread(buffer, sizeof(uint8_t), 4096, f);
+ if (read_len <= 0) {
+ LOGERR("Read size during try decrypt failed\n");
+ fclose(f);
+ return -1;
+ }
+ if (oaes_decrypt(ctx, buffer, read_len, NULL, &out_len) != OAES_RET_SUCCESS) {
+ LOGERR("Error: Failed to retrieve required buffer size for trying decryption.\n");
+ fclose(f);
+ return -1;
+ }
+ buffer_out = (uint8_t *) calloc(out_len, sizeof(char));
+ if (buffer_out == NULL) {
+ LOGERR("Failed to allocate output buffer for try decrypt.\n");
+ fclose(f);
+ return -1;
+ }
+ if (oaes_decrypt(ctx, buffer, read_len, buffer_out, &out_len) != OAES_RET_SUCCESS) {
+ LOGERR("Failed to decrypt file '%s'\n", fn.c_str());
+ fclose(f);
+ free(buffer_out);
+ return 0;
+ }
+ fclose(f);
+ if (out_len < 2) {
+ LOGINFO("Successfully decrypted '%s' but read length %i too small.\n", fn.c_str(), out_len);
+ free(buffer_out);
+ return 1; // Decrypted successfully
+ }
+ ptr = buffer_out;
+ firstbyte = *ptr & 0xff;
+ ptr++;
+ secondbyte = *ptr & 0xff;
+ if (firstbyte == 0x1f && secondbyte == 0x8b) {
+ LOGINFO("Successfully decrypted '%s' and file is compressed.\n", fn.c_str());
+ free(buffer_out);
+ return 3; // Compressed
+ }
+ if (out_len >= 262) {
+ ptr = buffer_out + 257;
+ if (strncmp((char*)ptr, "ustar", 5) == 0) {
+ LOGINFO("Successfully decrypted '%s' and file is tar format.\n", fn.c_str());
+ free(buffer_out);
+ return 2; // Tar
+ }
+ }
+ free(buffer_out);
+ LOGINFO("No errors decrypting '%s' but no known file format.\n", fn.c_str());
+ return 1; // Decrypted successfully
+#else
+ LOGERR("Encrypted backup support not included.\n");
+ return -1;
+#endif
+}
+
+unsigned long TWFunc::Get_File_Size(string Path) {
+ struct stat st;
+
+ if (stat(Path.c_str(), &st) != 0)
+ return 0;
+ return st.st_size;
+}
+
+#ifndef BUILD_TWRPTAR_MAIN
+
// Returns "/path" from a full /path/to/file.name
string TWFunc::Get_Root_Path(string Path) {
string Local_Path = Path;
@@ -206,15 +367,6 @@ int TWFunc::Recursive_Mkdir(string Path) {
return true;
}
-bool TWFunc::Path_Exists(string Path) {
- // Check to see if the Path exists
- struct stat st;
- if (stat(Path.c_str(), &st) != 0)
- return false;
- else
- return true;
-}
-
void TWFunc::GUI_Operation_Text(string Read_Value, string Default_Text) {
string Display_Text;
@@ -237,14 +389,6 @@ void TWFunc::GUI_Operation_Text(string Read_Value, string Partition_Name, string
DataManager::SetValue("tw_partition", Partition_Name);
}
-unsigned long TWFunc::Get_File_Size(string Path) {
- struct stat st;
-
- if (stat(Path.c_str(), &st) != 0)
- return 0;
- return st.st_size;
-}
-
void TWFunc::Copy_Log(string Source, string Destination) {
PartitionManager.Mount_By_Path(Destination, false);
FILE *destination_log = fopen(Destination.c_str(), "a");
@@ -478,30 +622,6 @@ int TWFunc::write_file(string fn, string& line) {
return -1;
}
-vector<string> TWFunc::split_string(const string &in, char del, bool skip_empty) {
- vector<string> res;
-
- if (in.empty() || del == '\0')
- return res;
-
- string field;
- istringstream f(in);
- if (del == '\n') {
- while(getline(f, field)) {
- if (field.empty() && skip_empty)
- continue;
- res.push_back(field);
- }
- } else {
- while(getline(f, field, del)) {
- if (field.empty() && skip_empty)
- continue;
- res.push_back(field);
- }
- }
- return res;
-}
-
timespec TWFunc::timespec_diff(timespec& start, timespec& end)
{
timespec temp;
@@ -559,13 +679,21 @@ bool TWFunc::Fix_su_Perms(void) {
if (!PartitionManager.Mount_By_Path("/system", true))
return false;
+ string propvalue = System_Property_Get("ro.build.version.sdk");
+ string su_perms = "6755";
+ if (!propvalue.empty()) {
+ int sdk_version = atoi(propvalue.c_str());
+ if (sdk_version >= 18)
+ su_perms = "0755";
+ }
+
string file = "/system/bin/su";
if (TWFunc::Path_Exists(file)) {
if (chown(file.c_str(), 0, 0) != 0) {
LOGERR("Failed to chown '%s'\n", file.c_str());
return false;
}
- if (tw_chmod(file, "6755") != 0) {
+ if (tw_chmod(file, su_perms) != 0) {
LOGERR("Failed to chmod '%s'\n", file.c_str());
return false;
}
@@ -576,7 +704,7 @@ bool TWFunc::Fix_su_Perms(void) {
LOGERR("Failed to chown '%s'\n", file.c_str());
return false;
}
- if (tw_chmod(file, "6755") != 0) {
+ if (tw_chmod(file, su_perms) != 0) {
LOGERR("Failed to chmod '%s'\n", file.c_str());
return false;
}
@@ -587,7 +715,7 @@ bool TWFunc::Fix_su_Perms(void) {
LOGERR("Failed to chown '%s'\n", file.c_str());
return false;
}
- if (tw_chmod(file, "6755") != 0) {
+ if (tw_chmod(file, "0755") != 0) {
LOGERR("Failed to chmod '%s'\n", file.c_str());
return false;
}
@@ -598,7 +726,7 @@ bool TWFunc::Fix_su_Perms(void) {
LOGERR("Failed to chown '%s'\n", file.c_str());
return false;
}
- if (tw_chmod(file, "6755") != 0) {
+ if (tw_chmod(file, su_perms) != 0) {
LOGERR("Failed to chmod '%s'\n", file.c_str());
return false;
}
@@ -802,121 +930,6 @@ bool TWFunc::Install_SuperSU(void) {
return true;
}
-int TWFunc::Get_File_Type(string fn) {
- string::size_type i = 0;
- int firstbyte = 0, secondbyte = 0;
- char header[3];
-
- ifstream f;
- f.open(fn.c_str(), ios::in | ios::binary);
- f.get(header, 3);
- f.close();
- firstbyte = header[i] & 0xff;
- secondbyte = header[++i] & 0xff;
-
- if (firstbyte == 0x1f && secondbyte == 0x8b)
- return 1; // Compressed
- else if (firstbyte == 0x4f && secondbyte == 0x41)
- return 2; // Encrypted
- else
- return 0; // Unknown
-
- return 0;
-}
-
-int TWFunc::Try_Decrypting_File(string fn, string password) {
-#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
- OAES_CTX * ctx = NULL;
- uint8_t _key_data[32] = "";
- FILE *f;
- uint8_t buffer[4096];
- uint8_t *buffer_out = NULL;
- uint8_t *ptr = NULL;
- size_t read_len = 0, out_len = 0;
- int firstbyte = 0, secondbyte = 0, key_len;
- size_t _j = 0;
- size_t _key_data_len = 0;
-
- // mostly kanged from OpenAES oaes.c
- for( _j = 0; _j < 32; _j++ )
- _key_data[_j] = _j + 1;
- _key_data_len = password.size();
- if( 16 >= _key_data_len )
- _key_data_len = 16;
- else if( 24 >= _key_data_len )
- _key_data_len = 24;
- else
- _key_data_len = 32;
- memcpy(_key_data, password.c_str(), password.size());
-
- ctx = oaes_alloc();
- if (ctx == NULL) {
- LOGERR("Failed to allocate OAES\n");
- return -1;
- }
-
- oaes_key_import_data(ctx, _key_data, _key_data_len);
-
- f = fopen(fn.c_str(), "rb");
- if (f == NULL) {
- LOGERR("Failed to open '%s' to try decrypt\n", fn.c_str());
- return -1;
- }
- read_len = fread(buffer, sizeof(uint8_t), 4096, f);
- if (read_len <= 0) {
- LOGERR("Read size during try decrypt failed\n");
- fclose(f);
- return -1;
- }
- if (oaes_decrypt(ctx, buffer, read_len, NULL, &out_len) != OAES_RET_SUCCESS) {
- LOGERR("Error: Failed to retrieve required buffer size for trying decryption.\n");
- fclose(f);
- return -1;
- }
- buffer_out = (uint8_t *) calloc(out_len, sizeof(char));
- if (buffer_out == NULL) {
- LOGERR("Failed to allocate output buffer for try decrypt.\n");
- fclose(f);
- return -1;
- }
- if (oaes_decrypt(ctx, buffer, read_len, buffer_out, &out_len) != OAES_RET_SUCCESS) {
- LOGERR("Failed to decrypt file '%s'\n", fn.c_str());
- fclose(f);
- free(buffer_out);
- return 0;
- }
- fclose(f);
- if (out_len < 2) {
- LOGINFO("Successfully decrypted '%s' but read length %i too small.\n", fn.c_str(), out_len);
- free(buffer_out);
- return 1; // Decrypted successfully
- }
- ptr = buffer_out;
- firstbyte = *ptr & 0xff;
- ptr++;
- secondbyte = *ptr & 0xff;
- if (firstbyte == 0x1f && secondbyte == 0x8b) {
- LOGINFO("Successfully decrypted '%s' and file is compressed.\n", fn.c_str());
- free(buffer_out);
- return 3; // Compressed
- }
- if (out_len >= 262) {
- ptr = buffer_out + 257;
- if (strncmp((char*)ptr, "ustar", 5) == 0) {
- LOGINFO("Successfully decrypted '%s' and file is tar format.\n", fn.c_str());
- free(buffer_out);
- return 2; // Tar
- }
- }
- free(buffer_out);
- LOGINFO("No errors decrypting '%s' but no known file format.\n", fn.c_str());
- return 1; // Decrypted successfully
-#else
- LOGERR("Encrypted backup support not included.\n");
- return -1;
-#endif
-}
-
bool TWFunc::Try_Decrypting_Backup(string Restore_Path, string Password) {
DIR* d;
@@ -945,31 +958,6 @@ bool TWFunc::Try_Decrypting_Backup(string Restore_Path, string Password) {
return true;
}
-int TWFunc::Wait_For_Child(pid_t pid, int *status, string Child_Name) {
- pid_t rc_pid;
-
- rc_pid = waitpid(pid, status, 0);
- if (rc_pid > 0) {
- if (WEXITSTATUS(*status) == 0)
- LOGINFO("%s process ended with RC=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Success
- else if (WIFSIGNALED(*status)) {
- LOGINFO("%s process ended with signal: %d\n", Child_Name.c_str(), WTERMSIG(*status)); // Seg fault or some other non-graceful termination
- return -1;
- } else if (WEXITSTATUS(*status) != 0) {
- LOGINFO("%s process ended with ERROR=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Graceful exit, but there was an error
- return -1;
- }
- } else { // no PID returned
- if (errno == ECHILD)
- LOGINFO("%s no child process exist\n", Child_Name.c_str());
- else {
- LOGINFO("%s Unexpected error\n", Child_Name.c_str());
- return -1;
- }
- }
- return 0;
-}
-
string TWFunc::Get_Current_Date() {
string Current_Date;
time_t seconds = time(0);
@@ -980,50 +968,56 @@ string TWFunc::Get_Current_Date() {
return Current_Date;
}
-void TWFunc::Auto_Generate_Backup_Name() {
+string TWFunc::System_Property_Get(string Prop_Name) {
bool mount_state = PartitionManager.Is_Mounted_By_Path("/system");
std::vector<string> buildprop;
- if (!PartitionManager.Mount_By_Path("/system", true)) {
- DataManager::SetValue(TW_BACKUP_NAME, Get_Current_Date());
- return;
- }
+ string propvalue;
+ if (!PartitionManager.Mount_By_Path("/system", true))
+ return propvalue;
if (TWFunc::read_file("/system/build.prop", buildprop) != 0) {
- LOGINFO("Unable to open /system/build.prop for getting backup name.\n");
+ LOGINFO("Unable to open /system/build.prop for getting '%s'.\n", Prop_Name.c_str());
DataManager::SetValue(TW_BACKUP_NAME, Get_Current_Date());
if (!mount_state)
PartitionManager.UnMount_By_Path("/system", false);
- return;
+ return propvalue;
}
int line_count = buildprop.size();
int index;
size_t start_pos = 0, end_pos;
- string propname, propvalue;
+ string propname;
for (index = 0; index < line_count; index++) {
end_pos = buildprop.at(index).find("=", start_pos);
propname = buildprop.at(index).substr(start_pos, end_pos);
- if (propname == "ro.build.display.id") {
+ if (propname == Prop_Name) {
propvalue = buildprop.at(index).substr(end_pos + 1, buildprop.at(index).size());
- string Backup_Name = Get_Current_Date();
- Backup_Name += " " + propvalue;
- if (Backup_Name.size() > MAX_BACKUP_NAME_LEN)
- Backup_Name.resize(MAX_BACKUP_NAME_LEN);
- // Trailing spaces cause problems on some file systems, so remove them
- string space_check, space = " ";
- space_check = Backup_Name.substr(Backup_Name.size() - 1, 1);
- while (space_check == space) {
- Backup_Name.resize(Backup_Name.size() - 1);
- space_check = Backup_Name.substr(Backup_Name.size() - 1, 1);
- }
- DataManager::SetValue(TW_BACKUP_NAME, Backup_Name);
- break;
+ if (!mount_state)
+ PartitionManager.UnMount_By_Path("/system", false);
+ return propvalue;
}
}
+ if (!mount_state)
+ PartitionManager.UnMount_By_Path("/system", false);
+ return propvalue;
+}
+
+void TWFunc::Auto_Generate_Backup_Name() {
+ string propvalue = System_Property_Get("ro.build.display.id");
if (propvalue.empty()) {
- LOGINFO("ro.build.display.id not found in build.prop\n");
DataManager::SetValue(TW_BACKUP_NAME, Get_Current_Date());
+ return;
}
- if (!mount_state)
- PartitionManager.UnMount_By_Path("/system", false);
+ string Backup_Name = Get_Current_Date();
+ Backup_Name += " " + propvalue;
+ if (Backup_Name.size() > MAX_BACKUP_NAME_LEN)
+ Backup_Name.resize(MAX_BACKUP_NAME_LEN);
+ // Trailing spaces cause problems on some file systems, so remove them
+ string space_check, space = " ";
+ space_check = Backup_Name.substr(Backup_Name.size() - 1, 1);
+ while (space_check == space) {
+ Backup_Name.resize(Backup_Name.size() - 1);
+ space_check = Backup_Name.substr(Backup_Name.size() - 1, 1);
+ }
+ DataManager::SetValue(TW_BACKUP_NAME, Backup_Name);
}
void TWFunc::Fixup_Time_On_Boot()
@@ -1118,3 +1112,5 @@ void TWFunc::Fixup_Time_On_Boot()
settimeofday(&tv, NULL);
#endif
}
+
+#endif // ndef BUILD_TWRPTAR_MAIN
diff --git a/twrp-functions.hpp b/twrp-functions.hpp
index 587d7725e..661ca02db 100644
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -42,20 +42,25 @@ public:
static string Get_Path(string Path); // Trims everything after the last / in the string
static string Get_Filename(string Path); // Trims the path off of a filename
+ static int Exec_Cmd(const string& cmd, string &result); //execute a command and return the result as a string by reference
+ static int Exec_Cmd(const string& cmd); //execute a command
+ static int Wait_For_Child(pid_t pid, int *status, string Child_Name); // Waits for pid to exit and checks exit status
+ static bool Path_Exists(string Path); // Returns true if the path exists
+ static int Get_File_Type(string fn); // Determines file type, 0 for unknown, 1 for gzip, 2 for OAES encrypted
+ static int Try_Decrypting_File(string fn, string password); // -1 for some error, 0 for failed to decrypt, 1 for decrypted, 3 for decrypted and found gzip format
+ static unsigned long Get_File_Size(string Path); // Returns the size of a file
+
+#ifndef BUILD_TWRPTAR_MAIN
static void install_htc_dumlock(void); // Installs HTC Dumlock
static void htc_dumlock_restore_original_boot(void); // Restores the backup of boot from HTC Dumlock
static void htc_dumlock_reflash_recovery_to_boot(void); // Reflashes the current recovery to boot
static int Recursive_Mkdir(string Path); // Recursively makes the entire path
- static bool Path_Exists(string Path); // Returns true if the path exists
static void GUI_Operation_Text(string Read_Value, string Default_Text); // Updates text for display in the GUI, e.g. Backing up %partition name%
static void GUI_Operation_Text(string Read_Value, string Partition_Name, string Default_Text); // Same as above but includes partition name
- static unsigned long Get_File_Size(string Path); // Returns the size of a file
static void Update_Log_File(void); // Writes the log to last_log
static void Update_Intent_File(string Intent); // Updates intent file
static int tw_reboot(RebootCommand command); // Prepares the device for rebooting
static void check_and_run_script(const char* script_file, const char* display_name); // checks for the existence of a script, chmods it to 755, then runs it
- static int Exec_Cmd(const string& cmd, string &result); //execute a command and return the result as a string by reference
- static int Exec_Cmd(const string& cmd); //execute a command
static int removeDir(const string path, bool removeParent); //recursively remove a directory
static int copy_file(string src, string dst, int mode); //copy file from src to dst with mode permissions
static unsigned int Get_D_Type_From_Stat(string Path); // Returns a dirent dt_type value using stat instead of dirent
@@ -69,11 +74,8 @@ public:
static bool Fix_su_Perms(void); // sets proper permissions for su binaries and superuser apk
static int tw_chmod(const string& fn, const string& mode); // chmod function that converts a 3 or 4 char string into st_mode automatically
static bool Install_SuperSU(void); // Installs su binary and apk and sets proper permissions
- static vector<string> split_string(const string &in, char del, bool skip_empty);
- static int Get_File_Type(string fn); // Determines file type, 0 for unknown, 1 for gzip, 2 for OAES encrypted
- static int Try_Decrypting_File(string fn, string password); // -1 for some error, 0 for failed to decrypt, 1 for decrypted, 3 for decrypted and found gzip format
static bool Try_Decrypting_Backup(string Restore_Path, string Password); // true for success, false for failed to decrypt
- static int Wait_For_Child(pid_t pid, int *status, string Child_Name); // Waits for pid to exit and checks exit status
+ static string System_Property_Get(string Prop_Name); // Returns value of Prop_Name from reading /system/build.prop
static string Get_Current_Date(void); // Returns the current date in ccyy-m-dd--hh-nn-ss format
static void Auto_Generate_Backup_Name(); // Populates TW_BACKUP_NAME with a backup name based on current date and ro.build.display.id from /system/build.prop
static void Fixup_Time_On_Boot(); // Fixes time on devices which need it
@@ -84,5 +86,8 @@ private:
};
extern int Log_Offset;
+#else
+};
+#endif // ndef BUILD_TWRPTAR_MAIN
#endif // _TWRPFUNCTIONS_HPP
diff --git a/twrpTar.cpp b/twrpTar.cpp
index 824356aae..cc09b78ab 100644
--- a/twrpTar.cpp
+++ b/twrpTar.cpp
@@ -21,7 +21,6 @@ extern "C" {
#include "libtar/libtar.h"
#include "twrpTar.h"
#include "tarWrite.h"
- #include "libcrecovery/common.h"
}
#include <sys/types.h>
#include <sys/stat.h>
@@ -39,7 +38,6 @@ extern "C" {
#include <sys/mman.h>
#include "twrpTar.hpp"
#include "twcommon.h"
-#include "data.hpp"
#include "variables.h"
#include "twrp-functions.hpp"
@@ -77,6 +75,10 @@ void twrpTar::setsize(unsigned long long backup_size) {
Total_Backup_Size = backup_size;
}
+void twrpTar::setpassword(string pass) {
+ password = pass;
+}
+
int twrpTar::createTarFork() {
int status = 0;
pid_t pid, rc_pid;
@@ -529,9 +531,7 @@ int twrpTar::extract() {
int ret = extractTar();
return ret;
} else if (Archive_Current_Type == 2) {
- string Password;
- DataManager::GetValue("tw_restore_password", Password);
- int ret = TWFunc::Try_Decrypting_File(tarfn, Password);
+ int ret = TWFunc::Try_Decrypting_File(tarfn, password);
if (ret < 1) {
LOGERR("Failed to decrypt tar file '%s'\n", tarfn.c_str());
return -1;
@@ -675,13 +675,11 @@ int twrpTar::createTar() {
char* charTarFile = (char*) tarfn.c_str();
char* charRootDir = (char*) tardir.c_str();
static tartype_t type = { open, close, read, write_tar };
- string Password;
if (use_encryption && use_compression) {
// Compressed and encrypted
Archive_Current_Type = 3;
LOGINFO("Using encryption and compression...\n");
- DataManager::GetValue("tw_backup_password", Password);
int i, pipes[4];
if (pipe(pipes) < 0) {
@@ -738,7 +736,7 @@ int twrpTar::createTar() {
dup2(pipes[2], 0);
close(1);
dup2(output_fd, 1);
- if (execlp("openaes", "openaes", "enc", "--key", Password.c_str(), NULL) < 0) {
+ if (execlp("openaes", "openaes", "enc", "--key", password.c_str(), NULL) < 0) {
LOGERR("execlp openaes ERROR!\n");
close(pipes[2]);
close(output_fd);
@@ -806,7 +804,6 @@ int twrpTar::createTar() {
// Encrypted
Archive_Current_Type = 2;
LOGINFO("Using encryption...\n");
- DataManager::GetValue("tw_backup_password", Password);
int oaesfd[2];
pipe(oaesfd);
oaes_pid = fork();
@@ -826,7 +823,7 @@ int twrpTar::createTar() {
}
dup2(oaesfd[0], 0); // remap stdin
dup2(output_fd, 1); // remap stdout to output file
- if (execlp("openaes", "openaes", "enc", "--key", Password.c_str(), NULL) < 0) {
+ if (execlp("openaes", "openaes", "enc", "--key", password.c_str(), NULL) < 0) {
LOGERR("execlp openaes ERROR!\n");
close(output_fd);
close(oaesfd[0]);
@@ -861,7 +858,6 @@ int twrpTar::openTar() {
if (Archive_Current_Type == 3) {
LOGINFO("Opening encrypted and compressed backup...\n");
- DataManager::GetValue("tw_restore_password", Password);
int i, pipes[4];
if (pipe(pipes) < 0) {
@@ -894,7 +890,7 @@ int twrpTar::openTar() {
dup2(input_fd, 0);
close(1);
dup2(pipes[1], 1);
- if (execlp("openaes", "openaes", "dec", "--key", Password.c_str(), NULL) < 0) {
+ if (execlp("openaes", "openaes", "dec", "--key", password.c_str(), NULL) < 0) {
LOGERR("execlp openaes ERROR!\n");
close(input_fd);
close(pipes[1]);
@@ -938,7 +934,6 @@ int twrpTar::openTar() {
}
} else if (Archive_Current_Type == 2) {
LOGINFO("Opening encrypted backup...\n");
- DataManager::GetValue("tw_restore_password", Password);
int oaesfd[2];
pipe(oaesfd);
@@ -960,7 +955,7 @@ int twrpTar::openTar() {
close(0); // close stdin
dup2(oaesfd[1], 1); // remap stdout
dup2(input_fd, 0); // remap input fd to stdin
- if (execlp("openaes", "openaes", "dec", "--key", Password.c_str(), NULL) < 0) {
+ if (execlp("openaes", "openaes", "dec", "--key", password.c_str(), NULL) < 0) {
LOGERR("execlp openaes ERROR!\n");
close(input_fd);
close(oaesfd[1]);
@@ -1119,38 +1114,6 @@ int twrpTar::entryExists(string entry) {
return ret;
}
-unsigned long long twrpTar::uncompressedSize() {
- int type = 0;
- unsigned long long total_size = 0;
- string Tar, Command, result;
- vector<string> split;
-
- Tar = TWFunc::Get_Filename(tarfn);
- type = TWFunc::Get_File_Type(tarfn);
- if (type == 0)
- total_size = TWFunc::Get_File_Size(tarfn);
- else {
- Command = "pigz -l " + tarfn;
- /* if we set Command = "pigz -l " + tarfn + " | sed '1d' | cut -f5 -d' '";
- we get the uncompressed size at once. */
- TWFunc::Exec_Cmd(Command, result);
- if (!result.empty()) {
- /* Expected output:
- compressed original reduced name
- 95855838 179403776 -1.3% data.yaffs2.win
- ^
- split[5]
- */
- split = TWFunc::split_string(result, ' ', true);
- if (split.size() > 4)
- total_size = atoi(split[5].c_str());
- }
- }
- LOGINFO("%s's uncompressed size: %llu bytes\n", Tar.c_str(), total_size);
-
- return total_size;
-}
-
extern "C" ssize_t write_tar(int fd, const void *buffer, size_t size) {
return (ssize_t) write_libtar_buffer(fd, buffer, size);
}
diff --git a/twrpTar.hpp b/twrpTar.hpp
index 17f69594d..a42dea0e1 100644
--- a/twrpTar.hpp
+++ b/twrpTar.hpp
@@ -51,7 +51,7 @@ public:
void setfn(string fn);
void setdir(string dir);
void setsize(unsigned long long backup_size);
- unsigned long long uncompressedSize();
+ void setpassword(string pass);
public:
int use_encryption;
@@ -89,6 +89,7 @@ private:
string tardir;
string tarfn;
string basefn;
+ string password;
vector <string> tarexclude;
diff --git a/twrpTarMain/Android.mk b/twrpTarMain/Android.mk
new file mode 100644
index 000000000..5cd6fe109
--- /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 000000000..ef6a5efea
--- /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;
+}