diff --git a/twrpTar.cpp b/twrpTar.cpp
new file mode 100644
index 0000000..0008de4
--- /dev/null
+++ b/twrpTar.cpp
@@ -0,0 +1,409 @@
+/*
+        Copyright 2012 bigbiff/Dees_Troy 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/>.
+*/
+
+extern "C" {
+	#include "libtar/libtar.h"
+}
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fstream>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <dirent.h>
+#include <sys/mman.h>
+#include "twrpTar.hpp"
+#include "common.h"
+#include "data.hpp"
+#include "variables.h"
+#include <sstream>
+#include "twrp-functions.hpp"
+
+using namespace std;
+
+int twrpTar::Generate_Multiple_Archives(string Path, string fn) {
+	DIR* d;
+	struct dirent* de;
+	struct stat st;
+	string FileName;
+	char actual_filename[255];
+
+	sprintf(actual_filename, fn.c_str(), Archive_File_Count);
+
+	if (has_data_media == 1 && Path.size() >= 11 && strncmp(Path.c_str(), "/data/media", 11) == 0)
+		return 0; // Skip /data/media
+	LOGI("Path: '%s', archive filename: '%s'\n", Path.c_str(), actual_filename);
+
+	d = opendir(Path.c_str());
+	if (d == NULL)
+	{
+		LOGE("error opening '%s' -- error: %s\n", Path.c_str(), strerror(errno));
+		closedir(d);
+		return -1;
+	}
+	while ((de = readdir(d)) != NULL)
+	{
+		FileName = Path + "/";
+		FileName += de->d_name;
+		if (has_data_media == 1 && FileName.size() >= 11 && strncmp(FileName.c_str(), "/data/media", 11) == 0)
+			continue; // Skip /data/media
+		if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
+		{
+			unsigned long long folder_size = TWFunc::Get_Folder_Size(FileName, false);
+			if (Archive_Current_Size + folder_size > MAX_ARCHIVE_SIZE) {
+				if (Generate_Multiple_Archives(FileName, fn) < 0)
+					return -1;
+			} else {
+				//FileName += "/";
+				LOGI("Adding folder '%s'\n", FileName.c_str());
+				if (tarDirs(FileName, actual_filename, true) < 0)
+					return -1;
+				Archive_Current_Size += folder_size;
+			}
+		}
+		else if (de->d_type == DT_REG || de->d_type == DT_LNK)
+		{
+			stat(FileName.c_str(), &st);
+
+			if (Archive_Current_Size != 0 && Archive_Current_Size + st.st_size > MAX_ARCHIVE_SIZE) {
+				LOGI("Closing tar '%s', ", actual_filename);
+				closeTar(actual_filename, false);
+				Archive_File_Count++;
+				if (TWFunc::Get_File_Size(actual_filename) == 0) {
+					LOGE("Backup file size for '%s' is 0 bytes.\n", actual_filename);
+					return false;
+				}
+				if (Archive_File_Count > 999) {
+					LOGE("Archive count is too large!\n");
+					return -1;
+				}
+				Archive_Current_Size = 0;
+				sprintf(actual_filename, fn.c_str(), Archive_File_Count);
+				LOGI("Creating tar '%s'\n", actual_filename);
+				ui_print("Creating archive %i...\n", Archive_File_Count + 1);
+				createTar(Path, actual_filename);
+			}
+			LOGI("Adding file: '%s'... ", FileName.c_str());
+			if (addFile(FileName, true) < 0)
+				return -1;
+			Archive_Current_Size += st.st_size;
+			LOGI("added successfully, archive size: %llu\n", Archive_Current_Size);
+			if (st.st_size > 2147483648LL)
+				LOGE("There is a file that is larger than 2GB in the file system\n'%s'\nThis file may not restore properly\n", FileName.c_str());
+		}
+	}
+	closedir(d);
+	return 0;
+}
+
+int twrpTar::Split_Archive(string Path, string fn)
+{
+	string temp = fn + "%03i";
+	char actual_filename[255];
+
+	Archive_File_Count = 0;
+	Archive_Current_Size = 0;
+	sprintf(actual_filename, temp.c_str(), Archive_File_Count);
+	createTar(Path, actual_filename);
+	DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
+	ui_print("Creating archive 1...\n");
+	if (Generate_Multiple_Archives(Path, temp) < 0) {
+		LOGE("Error generating file list\n");
+		return -1;
+	}
+	sprintf(actual_filename, temp.c_str(), Archive_File_Count);
+	closeTar(actual_filename, false);
+	LOGI("Done, created %i archives.\n", (Archive_File_Count++));
+	return (Archive_File_Count);
+}
+
+int twrpTar::extractTar(string rootdir, string fn) {
+        char* charRootDir = (char*) rootdir.c_str();
+	bool gzip = false;
+	if (openTar(rootdir, fn, gzip) == -1)
+		return -1;
+	if (tar_extract_all(t, charRootDir) != 0) {
+		LOGE("Unable to extract tar archive '%s'\n", fn.c_str());
+		return -1;
+	}
+	if (tar_close(t) != 0) {
+		LOGE("Unable to close tar file\n");
+		return -1;
+	}
+	return 0;
+}
+
+int twrpTar::extract(string rootdir, string fn) {
+        int len = 3;
+        char header[len];
+        string::size_type i = 0;
+        int firstbyte = 0;
+        int secondbyte = 0;
+        int ret;
+        ifstream f;
+        f.open(fn.c_str(), ios::in | ios::binary);
+        f.get(header, len);
+        firstbyte = header[i] & 0xff;
+        secondbyte = header[++i] & 0xff;
+        f.close();
+        if (firstbyte == 0x1f && secondbyte == 0x8b) {
+		//if you return the extractTGZ function directly, stack crashes happen
+		LOGI("Extracting gzipped tar\n");
+		ret = extractTGZ(rootdir, fn);
+		return ret;
+	}
+	else {
+		LOGI("Extracting uncompressed tar\n");
+		return extractTar(rootdir, fn);
+	}
+}
+
+int twrpTar::tarDirs(string dir, string fn, bool include_root) {
+        DIR* d;
+        string mainfolder = dir + "/", subfolder;
+        char buf[1024];
+        char* charTarFile = (char*) fn.c_str();
+        d = opendir(dir.c_str());
+        if (d != NULL) {
+                struct dirent* de;
+                while ((de = readdir(d)) != NULL) {
+                        LOGI("adding %s\n", de->d_name);
+#ifdef RECOVERY_SDCARD_ON_DATA
+                        if ((dir == "/data" || dir == "/data/") && strcmp(de->d_name, "media") == 0) continue;
+#endif
+                        if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)   continue;
+
+                        subfolder = mainfolder;
+                        subfolder += de->d_name;
+                        strcpy(buf, subfolder.c_str());
+                        if (de->d_type == DT_DIR) {
+							if (include_root) {
+                                if (tar_append_tree(t, buf, NULL) != 0) {
+                                        LOGE("Error appending '%s' to tar archive '%s'\n", buf, charTarFile);
+                                        return -1;
+                                }
+							} else {
+								string temp = Strip_Root_Dir(buf);
+								char* charTarPath = (char*) temp.c_str();
+								if (tar_append_tree(t, buf, charTarPath) != 0) {
+                                        LOGE("Error appending '%s' to tar archive '%s'\n", buf, charTarFile);
+                                        return -1;
+                                }
+							}
+                        } else if (dir != "/" && (de->d_type == DT_REG || de->d_type == DT_LNK)) {
+							if (addFile(buf, include_root) != 0)
+								return -1;
+						}
+                        fflush(NULL);
+                }
+                closedir(d);
+        }
+	return 0;
+}
+
+int twrpTar::createTGZ(string dir, string fn) {
+        bool gzip = true;
+	if (createTar(dir, fn) == -1)
+		return -1;
+	if (tarDirs(dir, fn, false) == -1)
+		return -1;
+	if (closeTar(fn, gzip) == -1)
+		return -1;
+        return 0;
+}
+
+int twrpTar::create(string dir, string fn) {
+        bool gzip = false;
+	if (createTar(dir, fn) == -1)
+		return -1;
+	if (tarDirs(dir, fn, false) == -1)
+		return -1;
+	if (closeTar(fn, gzip) == -1)
+		return -1;
+	return 0;
+}
+
+int twrpTar::addFilesToExistingTar(vector <string> files, string fn) {
+	char* charTarFile = (char*) fn.c_str();
+
+	if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) == -1)
+		return -1;
+	removeEOT(charTarFile);
+	if (tar_open(&t, charTarFile, NULL, O_WRONLY | O_APPEND | O_LARGEFILE, 0644, TAR_GNU) == -1)
+		return -1;
+	for (unsigned int i = 0; i < files.size(); ++i) {
+		char* file = (char*) files.at(i).c_str(); 
+		if (tar_append_file(t, file, file) == -1)
+			return -1;
+	}
+	if (tar_append_eof(t) == -1)
+		return -1;
+	if (tar_close(t) == -1)
+		return -1;
+	return 0;
+}
+
+int twrpTar::createTar(string rootdir, string fn) {
+	char* charTarFile = (char*) fn.c_str();
+        char* charRootDir = (char*) rootdir.c_str();
+	int use_compression = 0;
+
+	DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
+	LOGI("2nd compression\n");
+	if (use_compression) {
+		string cmd = "pigz - > '" + fn + "'";
+		p = popen(cmd.c_str(), "w");
+		fd = fileno(p);
+		if (!p) return -1;
+		if(tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+			pclose(p);
+			return -1;
+		}
+	}	
+	else {
+		if (tar_open(&t, charTarFile, NULL, O_WRONLY | O_CREAT | O_LARGEFILE, 0644, TAR_GNU) == -1)
+			return -1;
+	}
+	return 0;
+}
+
+int twrpTar::openTar(string rootdir, string fn, bool gzip) {
+        char* charRootDir = (char*) rootdir.c_str();
+        char* charTarFile = (char*) fn.c_str();
+
+	if (gzip) {
+		LOGI("Opening as a gzip\n");
+		string cmd = "pigz -d -c '" + fn + "'";
+		FILE* pipe = popen(cmd.c_str(), "r");
+		int fd = fileno(pipe);
+		if (!pipe) return -1;
+		if(tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+			LOGI("tar_fdopen returned error\n");
+			pclose(pipe);
+			return -1;
+		}
+	}
+	else {
+		if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+			LOGE("Unable to open tar archive '%s'\n", charTarFile);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+string twrpTar::Strip_Root_Dir(string Path) {
+	string temp;
+	size_t slash;
+
+	if (Path.substr(0, 1) == "/")
+		temp = Path.substr(1, Path.size() - 1);
+	else
+		temp = Path;
+	slash = temp.find("/");
+	if (slash == string::npos)
+		return temp;
+	else {
+		string stripped;
+
+		stripped = temp.substr(slash, temp.size() - slash);
+		return stripped;
+	}
+	return temp;
+}
+
+int twrpTar::addFile(string fn, bool include_root) {
+	char* charTarFile = (char*) fn.c_str();
+	if (include_root) {
+		if (tar_append_file(t, charTarFile, NULL) == -1)
+			return -1;
+	} else {
+		string temp = Strip_Root_Dir(fn);
+		char* charTarPath = (char*) temp.c_str();
+		if (tar_append_file(t, charTarFile, charTarPath) == -1)
+			return -1;
+	}
+	return 0;
+}
+
+int twrpTar::closeTar(string fn, bool gzip) {
+	int use_compression;
+	DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
+
+	if (tar_append_eof(t) != 0) {
+		LOGE("tar_append_eof(): %s\n", strerror(errno));
+		tar_close(t);
+		return -1;
+	}
+	if (tar_close(t) != 0) {
+		LOGE("Unable to close tar archive: '%s'\n", fn.c_str());
+		return -1;
+	}
+	if (use_compression || gzip) {
+		LOGI("Closing popen and fd\n");
+		pclose(p);
+		close(fd);
+	}
+	return 0;
+}
+
+int twrpTar::removeEOT(string tarFile) {
+	char* charTarFile = (char*) tarFile.c_str();
+	off_t tarFileEnd;
+	while (th_read(t) == 0) {
+		if (TH_ISREG(t)) 
+			tar_skip_regfile(t);
+		tarFileEnd = lseek(t->fd, 0, SEEK_CUR);
+	}	
+	if (tar_close(t) == -1)
+		return -1;
+	if (truncate(charTarFile, tarFileEnd) == -1) 
+		return -1;
+	return 0;
+}
+
+int twrpTar::compress(string fn) {
+	string cmd = "pigz " + fn; 
+	p = popen(cmd.c_str(), "r");
+	if (!p) return -1;
+	char buffer[128];
+	string result = "";
+	while(!feof(p)) {
+		if(fgets(buffer, 128, p) != NULL)
+			result += buffer;
+	}
+	pclose(p);
+	return 0;
+}
+
+int twrpTar::extractTGZ(string rootdir, string fn) {
+	string splatrootdir(rootdir);
+	bool gzip = true;
+        char* splatCharRootDir = (char*) splatrootdir.c_str();
+	if (openTar(rootdir, fn, gzip) == -1)
+		return -1;
+	int ret = tar_extract_all(t, splatCharRootDir);
+	if (tar_close(t) != 0) {
+		LOGE("Unable to close tar file\n");
+		return -1;
+	}
+        return 0;
+}
