Merge "Don't switch between fast and normal scroll during drag in listviews" into android-4.4
diff --git a/fixPermissions.cpp b/fixPermissions.cpp
index fa5ef56..40ac516 100644
--- a/fixPermissions.cpp
+++ b/fixPermissions.cpp
@@ -45,8 +45,10 @@
 int fixPermissions::restorecon(string entry, struct stat *sb) {
 	char *oldcontext, *newcontext;
 	struct selabel_handle *sehandle;
-
-	sehandle = selinux_android_file_context_handle();
+	struct selinux_opt selinux_options[] = {
+		{ SELABEL_OPT_PATH, "/file_contexts" }
+	};
+	sehandle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
 	if (lgetfilecon(entry.c_str(), &oldcontext) < 0) {
 		LOGINFO("Couldn't get selinux context for %s\n", entry.c_str());
 		return -1;
diff --git a/minui/Android.mk b/minui/Android.mk
index 9bda6dd..d889587 100644
--- a/minui/Android.mk
+++ b/minui/Android.mk
@@ -31,4 +31,8 @@
   LOCAL_CFLAGS += -DOVERSCAN_PERCENT=0
 endif
 
+ifneq ($(TARGET_RECOVERY_LCD_BACKLIGHT_PATH),)
+  LOCAL_CFLAGS += -DRECOVERY_LCD_BACKLIGHT_PATH=$(TARGET_RECOVERY_LCD_BACKLIGHT_PATH)
+endif
+
 include $(BUILD_STATIC_LIBRARY)
diff --git a/minui/graphics.c b/minui/graphics.c
index 8998d9f..ff39674 100644
--- a/minui/graphics.c
+++ b/minui/graphics.c
@@ -437,9 +437,21 @@
 
 void gr_fb_blank(bool blank)
 {
+#ifdef RECOVERY_LCD_BACKLIGHT_PATH
+    int fd;
+
+    fd = open(RECOVERY_LCD_BACKLIGHT_PATH, O_RDWR);
+    if (fd < 0) {
+        perror("cannot open LCD backlight");
+        return;
+    }
+    write(fd, blank ? "000" : "127", 3);
+    close(fd);
+#else
     int ret;
 
     ret = ioctl(gr_fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
     if (ret < 0)
         perror("ioctl(): blank");
+#endif
 }
diff --git a/minuitwrp/graphics.c b/minuitwrp/graphics.c
index fc34b6b..99f5841 100644
--- a/minuitwrp/graphics.c
+++ b/minuitwrp/graphics.c
@@ -69,6 +69,7 @@
 static GGLSurface gr_mem_surface;
 static unsigned gr_active_fb = 0;
 static unsigned double_buffering = 0;
+static int gr_is_curr_clr_opaque = 0;
 
 static int gr_fb_fd = -1;
 static int gr_vt_fd = -1;
@@ -288,6 +289,8 @@
     color[2] = ((b << 8) | b) + 1;
     color[3] = ((a << 8) | a) + 1;
     gl->color4xv(gl, color);
+
+    gr_is_curr_clr_opaque = (a == 255);
 }
 
 int gr_measureEx(const char *s, void* font)
@@ -463,8 +466,15 @@
 void gr_fill(int x, int y, int w, int h)
 {
     GGLContext *gl = gr_context;
+
+    if(gr_is_curr_clr_opaque)
+        gl->disable(gl, GGL_BLEND);
+
     gl->disable(gl, GGL_TEXTURE_2D);
     gl->recti(gl, x, y, x + w, y + h);
+
+    if(gr_is_curr_clr_opaque)
+        gl->enable(gl, GGL_BLEND);
 }
 
 void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) {
diff --git a/partition.cpp b/partition.cpp
index 31b1bfd..95f6bca 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -74,10 +74,18 @@
 	{ "remount",    MS_REMOUNT },
 	{ "bind",       MS_BIND },
 	{ "rec",        MS_REC },
+#ifdef MS_UNBINDABLE
 	{ "unbindable", MS_UNBINDABLE },
+#endif
+#ifdef MS_PRIVATE
 	{ "private",    MS_PRIVATE },
+#endif
+#ifdef MS_SLAVE
 	{ "slave",      MS_SLAVE },
+#endif
+#ifdef MS_SHARED
 	{ "shared",     MS_SHARED },
+#endif
 	{ "sync",       MS_SYNCHRONOUS },
 	{ "defaults",   0 },
 	{ 0,            0 },
@@ -353,10 +361,6 @@
 			Is_Storage = true;
 			Removable = true;
 			Wipe_Available_in_GUI = true;
-#ifndef RECOVERY_SDCARD_ON_DATA
-			Setup_AndSec();
-			Mount_Storage_Retry();
-#endif
 #endif
 		}
 #ifdef TW_INTERNAL_STORAGE_PATH
@@ -365,20 +369,12 @@
 			Is_Settings_Storage = true;
 			Storage_Path = EXPAND(TW_INTERNAL_STORAGE_PATH);
 			Wipe_Available_in_GUI = true;
-#ifndef RECOVERY_SDCARD_ON_DATA
-			Setup_AndSec();
-			Mount_Storage_Retry();
-#endif
 		}
 #else
 		if (Mount_Point == "/emmc" || Mount_Point == "/internal_sd" || Mount_Point == "/internal_sdcard") {
 			Is_Storage = true;
 			Is_Settings_Storage = true;
 			Wipe_Available_in_GUI = true;
-#ifndef RECOVERY_SDCARD_ON_DATA
-			Setup_AndSec();
-			Mount_Storage_Retry();
-#endif
 		}
 #endif
 	} else if (Is_Image(Fstab_File_System)) {
@@ -391,7 +387,6 @@
 		} else if (Mount_Point == "/recovery") {
 			Display_Name = "Recovery";
 			Backup_Display_Name = Display_Name;
-			Can_Be_Backed_Up = true;
 		}
 	}
 
@@ -458,8 +453,20 @@
 		ptr_len = strlen(ptr);
 		if (strcmp(ptr, "removable") == 0) {
 			Removable = true;
-		} else if (strcmp(ptr, "storage") == 0) {
-			Is_Storage = true;
+		} else if (strncmp(ptr, "storage", 7) == 0) {
+			if (ptr_len == 7) {
+				LOGINFO("ptr_len is 7, storage set to true\n");
+				Is_Storage = true;
+			} else if (ptr_len == 9) {
+				ptr += 9;
+				if (*ptr == '1' || *ptr == 'y' || *ptr == 'Y') {
+					LOGINFO("storage set to true\n");
+					Is_Storage = true;
+				} else {
+					LOGINFO("storage set to false\n");
+					Is_Storage = false;
+				}
+			}
 		} else if (strcmp(ptr, "settingsstorage") == 0) {
 			Is_Storage = true;
 		} else if (strcmp(ptr, "canbewiped") == 0) {
@@ -644,6 +651,7 @@
 	Backup_Path = Symlink_Mount_Point;
 	Make_Dir("/and-sec", true);
 	Recreate_AndSec_Folder();
+	Mount_Storage_Retry();
 }
 
 void TWPartition::Find_Real_Block_Device(string& Block, bool Display_Error) {
@@ -1519,8 +1527,9 @@
 			// The media folder is the "internal sdcard"
 			// The .layout_version file is responsible for determining whether 4.2 decides up upgrade
 			// the media folder for multi-user.
+			//TODO: convert this to use twrpDU.cpp
 			if (strcmp(de->d_name, "media") == 0 || strcmp(de->d_name, ".layout_version") == 0)   continue;
-			
+
 			dir = "/data/";
 			dir.append(de->d_name);
 			if (de->d_type == DT_DIR) {
@@ -1531,6 +1540,7 @@
 			}
 		}
 		closedir(d);
+
 		gui_print("Done.\n");
 		return true;
 	}
@@ -1575,35 +1585,12 @@
 	Backup_FileName = back_name;
 	Full_FileName = backup_folder + "/" + Backup_FileName;
 	tar.has_data_media = Has_Data_Media;
-	if (!use_encryption && Backup_Size > MAX_ARCHIVE_SIZE) {
-		// This backup needs to be split into multiple archives
-		gui_print("Breaking backup file into multiple archives...\n");
-		sprintf(back_name, "%s", Backup_Path.c_str());
-		tar.setdir(back_name);
-		tar.setfn(Full_FileName);
-		backup_count = tar.splitArchiveFork();
-		if (backup_count == -1) {
-			LOGERR("Error tarring split files!\n");
-			return false;
-		}
-		return true;
-	} else {
-		Full_FileName = backup_folder + "/" + Backup_FileName;
-		tar.setdir(Backup_Path);
-		tar.setfn(Full_FileName);
-		if (tar.createTarFork() != 0)
-			return false;
-		if (use_compression && !use_encryption) {
-			string gzname = Full_FileName + ".gz";
-			rename(gzname.c_str(), Full_FileName.c_str());
-		}
-		if (use_encryption)
-			Full_FileName += "000";
-		if (TWFunc::Get_File_Size(Full_FileName) == 0) {
-			LOGERR("Backup file size for '%s' is 0 bytes.\n", Full_FileName.c_str());
-			return false;
-		}
-	}
+	Full_FileName = backup_folder + "/" + Backup_FileName;
+	tar.setdir(Backup_Path);
+	tar.setfn(Full_FileName);
+	tar.setsize(Backup_Size);
+	if (tar.createTarFork() != 0)
+		return false;
 	return true;
 }
 
@@ -1778,6 +1765,7 @@
 			unsigned long long data_media_used, actual_data;
 			du.add_relative_dir("media");
 			Used = du.Get_Folder_Size("/data");
+			du.clear_relative_dir("media");
 			Backup_Size = Used;
 			int bak = (int)(Used / 1048576LLU);
 			int fre = (int)(Free / 1048576LLU);
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 091ae32..04dbee9 100644
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -96,6 +96,9 @@
 		for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
 			if ((*iter)->Is_Storage) {
 				(*iter)->Is_Settings_Storage = true;
+#ifndef RECOVERY_SDCARD_ON_DATA
+				(*iter)->Setup_AndSec();
+#endif
 				Found_Settings_Storage = true;
 				DataManager::SetValue("tw_settings_path", (*iter)->Storage_Path);
 				DataManager::SetValue("tw_storage_path", (*iter)->Storage_Path);
diff --git a/twrpDU.cpp b/twrpDU.cpp
index 66c8031..c4446d4 100644
--- a/twrpDU.cpp
+++ b/twrpDU.cpp
@@ -43,6 +43,16 @@
 	relativedir.push_back(dir);
 }
 
+void twrpDU::clear_relative_dir(string dir) {
+	vector<string>::iterator iter = relativedir.begin();
+	while (iter != relativedir.end()) {
+		if (*iter == dir)
+			iter = relativedir.erase(iter);
+		else
+			iter++;
+	}
+}
+
 void twrpDU::add_absolute_dir(string dir) {
 	absolutedir.push_back(dir);
 }
@@ -97,7 +107,6 @@
 		}
 	}
 	for (int i = 0; i < absolutedir.size(); ++i) {
-		//string absdir = parent + dir;
 		if (dir == absolutedir.at(i)) {
 			result = true;
 			break;
diff --git a/twrpDU.hpp b/twrpDU.hpp
index 04527cd..dac15f1 100644
--- a/twrpDU.hpp
+++ b/twrpDU.hpp
@@ -40,8 +40,9 @@
 	uint64_t Get_Folder_Size(const string& Path); // Gets the folder's size using stat
 	void add_absolute_dir(string Path);
 	void add_relative_dir(string Path);
-	bool check_skip_dirs(string& dir);            // Checks a list of directories to see if we should skip it
+	bool check_skip_dirs(string& dir);
 	vector<string> get_absolute_dirs(void);
+	void clear_relative_dir(string dir);
 private:
 	vector<string> absolutedir;
 	vector<string> relativedir;
diff --git a/twrpTar.cpp b/twrpTar.cpp
index e77e1d0..824356a 100644
--- a/twrpTar.cpp
+++ b/twrpTar.cpp
@@ -1,3 +1,4 @@
+
 /*
 	Copyright 2013 TeamWin
 	This file is part of TWRP/TeamWin Recovery Project.
@@ -52,6 +53,8 @@
 	has_data_media = 0;
 	pigz_pid = 0;
 	oaes_pid = 0;
+	Total_Backup_Size = 0;
+	include_root_dir = true;
 }
 
 twrpTar::~twrpTar(void) {
@@ -70,6 +73,10 @@
 	tarexclude.push_back(exclude);
 }
 
+void twrpTar::setsize(unsigned long long backup_size) {
+	Total_Backup_Size = backup_size;
+}
+
 int twrpTar::createTarFork() {
 	int status = 0;
 	pid_t pid, rc_pid;
@@ -203,6 +210,7 @@
 				reg.thread_id = 0;
 				reg.use_encryption = 0;
 				reg.use_compression = use_compression;
+				reg.split_archives = 1;
 				LOGINFO("Creating unencrypted backup...\n");
 				if (createList((void*)&reg) != 0) {
 					LOGERR("Error creating unencrypted backup.\n");
@@ -235,6 +243,7 @@
 				enc[i].thread_id = i;
 				enc[i].use_encryption = use_encryption;
 				enc[i].use_compression = use_compression;
+				enc[i].split_archives = 1;
 				LOGINFO("Start encryption thread %i\n", i);
 				ret = pthread_create(&enc_thread[i], &tattr, createList, (void*)&enc[i]);
 				if (ret) {
@@ -276,10 +285,35 @@
 			LOGINFO("Finished encrypted backup.\n");
 			_exit(0);
 		} else {
-			if (create() != 0)
+			std::vector<TarListStruct> FileList;
+			unsigned thread_id = 0;
+			unsigned long long target_size = 0;
+			twrpTar reg;
+
+			// Generate list of files to back up
+			if (Generate_TarList(tardir, &FileList, &target_size, &thread_id) < 0) {
+				LOGERR("Error in Generate_TarList!\n");
 				_exit(-1);
-			else
-				_exit(0);
+			}
+			// Create a backup
+			reg.setfn(tarfn);
+			reg.ItemList = &FileList;
+			reg.thread_id = 0;
+			reg.use_encryption = 0;
+			reg.use_compression = use_compression;
+			reg.setsize(Total_Backup_Size);
+			if (Total_Backup_Size > MAX_ARCHIVE_SIZE) {
+				gui_print("Breaking backup file into multiple archives...\n");
+				reg.split_archives = 1;
+			} else {
+				reg.split_archives = 0;
+			}
+			LOGINFO("Creating backup...\n");
+			if (createList((void*)&reg) != 0) {
+				LOGERR("Error creating backup.\n");
+				_exit(-1);
+			}
+			_exit(0);
 		}
 	} else {
 		if (TWFunc::Wait_For_Child(pid, &status, "createTarFork()") != 0)
@@ -410,34 +444,6 @@
 	return 0;
 }
 
-int twrpTar::splitArchiveFork() {
-	int status = 0;
-	pid_t pid, rc_pid;
-
-	pid = fork();
-	if (pid >= 0) // fork was successful
-	{
-		if (pid == 0) // child process
-		{
-			if (Split_Archive() <= 0)
-				_exit(-1);
-			else
-				_exit(0);
-		}
-		else // parent process
-		{
-			if (TWFunc::Wait_For_Child(pid, &status, "splitArchiveFork()") != 0)
-				return -1;
-		}
-	}
-	else // fork has failed
-	{
-		LOGINFO("split archive failed to fork.\n");
-		return -1;
-	}
-	return 0;
-}
-
 int twrpTar::Generate_TarList(string Path, std::vector<TarListStruct> *TarList, unsigned long long *Target_Size, unsigned *thread_id) {
 	DIR* d;
 	struct dirent* de;
@@ -452,26 +458,25 @@
 
 	d = opendir(Path.c_str());
 	if (d == NULL) {
-		LOGERR("error opening '%s' -- error: %s\n", Path.c_str(), strerror(errno));
+		LOGERR("Error opening '%s' -- error: %s\n", Path.c_str(), strerror(errno));
 		closedir(d);
 		return -1;
 	}
 	while ((de = readdir(d)) != NULL) {
 		// Skip excluded stuff
-		if (split.size() > 0) {
+		FileName = Path + "/";
+		FileName += de->d_name;
+		if (tarexclude.size() > 0) {
 			skip = false;
-			for (i = 0; i < split.size(); i++) {
-				if (strcmp(de->d_name, split[i].c_str()) == 0) {
-					LOGINFO("excluding %s\n", de->d_name);
-					skip = true;
+			for (i = 0; i < tarexclude.size(); i++) {
+				if (FileName == tarexclude[i]) {
+					LOGINFO("Excluding %s\n", FileName.c_str());
 					break;
 				}
 			}
 			if (skip)
 				continue;
 		}
-		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_BLK || de->d_type == DT_CHR)
@@ -500,144 +505,6 @@
 	return 0;
 }
 
-int twrpTar::Generate_Multiple_Archives(string Path) {
-	DIR* d;
-	struct dirent* de;
-	struct stat st;
-	string FileName;
-	char actual_filename[255];
-
-	string::size_type i;
-	bool skip;
-
-	if (has_data_media == 1 && Path.size() >= 11 && strncmp(Path.c_str(), "/data/media", 11) == 0)
-		return 0; // Skip /data/media
-	LOGINFO("Path: '%s', archive filename: '%s'\n", Path.c_str(), tarfn.c_str());
-
-	d = opendir(Path.c_str());
-	if (d == NULL)
-	{
-		LOGERR("error opening '%s' -- error: %s\n", Path.c_str(), strerror(errno));
-		closedir(d);
-		return -1;
-	}
-	while ((de = readdir(d)) != NULL) {
-		// Skip excluded stuff
-		if (split.size() > 0) {
-			skip = false;
-			for (i = 0; i < split.size(); i++) {
-				if (strcmp(de->d_name, split[i].c_str()) == 0) {
-					LOGINFO("excluding %s\n", de->d_name);
-					skip = true;
-					break;
-				}
-			}
-			if (skip) {
-				continue;
-			}
-		}
-		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_BLK || de->d_type == DT_CHR)
-			continue;
-		if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
-		{
-			uint64_t folder_size = du.Get_Folder_Size(FileName);
-			if (Archive_Current_Size + folder_size > MAX_ARCHIVE_SIZE) {
-				// Add the root folder first
-				LOGINFO("Adding root folder '%s' before splitting.\n", FileName.c_str());
-				if (addFile(FileName, true) != 0) {
-					LOGERR("Error adding folder '%s' to split archive.\n", FileName.c_str());
-					return -1;
-				}
-				LOGINFO("Calling Generate_Multiple_Archives\n");
-				if (Generate_Multiple_Archives(FileName) < 0)
-					return -1;
-			} else {
-				//FileName += "/";
-				LOGINFO("Adding folder '%s'\n", FileName.c_str());
-				tardir = FileName;
-				if (tarDirs(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 (de->d_type != DT_LNK) {
-				if (Archive_Current_Size != 0 && Archive_Current_Size + st.st_size > MAX_ARCHIVE_SIZE) {
-					LOGINFO("Closing tar '%s', ", tarfn.c_str());
-					closeTar();
-					if (TWFunc::Get_File_Size(tarfn) == 0) {
-						LOGERR("Backup file size for '%s' is 0 bytes.\n", tarfn.c_str());
-						return -1;
-					}
-					Archive_File_Count++;
-					if (Archive_File_Count > 999) {
-						LOGERR("Archive count is too large!\n");
-						return -1;
-					}
-					string temp = basefn + "%03i";
-					sprintf(actual_filename, temp.c_str(), Archive_File_Count);
-					tarfn = actual_filename;
-					Archive_Current_Size = 0;
-					LOGINFO("Creating tar '%s'\n", tarfn.c_str());
-					gui_print("Creating archive %i...\n", Archive_File_Count + 1);
-					if (createTar() != 0)
-						return -1;
-				}
-			}
-			LOGINFO("Adding file: '%s'... ", FileName.c_str());
-			if (addFile(FileName, true) < 0)
-				return -1;
-			if (de->d_type != DT_LNK) {
-				Archive_Current_Size += st.st_size;
-			}
-			LOGINFO("added successfully, archive size: %llu\n", Archive_Current_Size);
-			if (de->d_type != DT_LNK) {
-				if (st.st_size > 2147483648LL)
-					LOGERR("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 temp = tarfn + "%03i";
-	char actual_filename[255];
-	string tarsplit;
-
-	basefn = tarfn;
-	Archive_File_Count = 0;
-	Archive_Current_Size = 0;
-	sprintf(actual_filename, temp.c_str(), Archive_File_Count);
-	tarfn = actual_filename;
-
-	for (int i = 0; i < tarexclude.size(); ++i) {
-		tarsplit = tarexclude[i];
-		tarsplit += " ";
-	}
-
-	if (!tarexclude.empty())
-		split = TWFunc::split_string(tarsplit, ' ', true);
-	createTar();
-	DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
-	gui_print("Creating archive 1...\n");
-	if (Generate_Multiple_Archives(tardir) < 0) {
-		LOGERR("Error generating multiple archives\n");
-		return -1;
-	}
-	closeTar();
-	LOGINFO("Done, created %i archives.\n", (++Archive_File_Count));
-	return (Archive_File_Count);
-}
-
 int twrpTar::extractTar() {
 	char* charRootDir = (char*) tardir.c_str();
 	if (openTar() == -1)
@@ -685,112 +552,24 @@
 	}
 }
 
-int twrpTar::tarDirs(bool include_root) {
-	DIR* d;
-	string mainfolder = tardir + "/", subfolder;
-	string tarsplit;
-	char buf[PATH_MAX], charTarPath[PATH_MAX];
-	string excl;
-	string::size_type i;
-	bool skip;
-
-	//set exclude directories for libtar
-	for (int i = 0; i < tarexclude.size(); ++i) {
-		excl += tarexclude.at(i);
-		tarsplit = tarexclude.at(i);
-		excl += " ";
-		tarsplit += " ";
-	}
-	d = opendir(tardir.c_str());
-	if (d != NULL) {
-		if (!tarsplit.empty()) {
-			split = TWFunc::split_string(tarsplit, ' ', true);
-		}
-		struct dirent* de;
-		while ((de = readdir(d)) != NULL) {
-		    bool skip_dir = false;
-#ifdef RECOVERY_SDCARD_ON_DATA
-			du.add_absolute_dir("/data/media");
-			string dir(tardir + "/" + de->d_name);
-		    skip_dir = du.check_skip_dirs(dir);
-			if (skip_dir) continue;
-#else
-			string dir;
-#endif
-			dir = de->d_name;
-		    skip_dir = du.check_skip_dirs(dir);
-			if (de->d_type == DT_BLK || de->d_type == DT_CHR || skip_dir)
-				continue;
-
-			// Skip excluded stuff
-			if (split.size() > 0) {
-				skip = false;
-				for (i = 0; i < split.size(); i++) {
-					if (strcmp(de->d_name, split[i].c_str()) == 0) {
-						LOGINFO("excluding %s\n", de->d_name);
-						skip = true;
-						break;
-					}
-				}
-				if (skip) {
-					continue;
-				}
-			}
-
-			subfolder = mainfolder;
-			if (strcmp(de->d_name, ".") != 0) {
-				subfolder += de->d_name;
-			} else {
-				std::string parentDir = basename(subfolder.c_str());
-				LOGINFO("parentDir: %s\n", parentDir.c_str());
-				if (!parentDir.compare("lost+found"))
-					continue;
-				LOGINFO("tarDirs addFile '%s' including root: %i\n", subfolder.c_str(), include_root);
-				if (addFile(subfolder, include_root) != 0)
-					return -1;
-				continue;
-			}
-			strcpy(buf, subfolder.c_str());
-			if (de->d_type == DT_DIR) {
-				if (include_root) {
-					charTarPath[0] = NULL;
-					LOGINFO("tar_append_tree '%s' as NULL\n", buf, charTarPath);
-					if (tar_append_tree(t, buf, NULL, &excl[0]) != 0) {
-						LOGERR("Error appending '%s' to tar archive '%s'\n", buf, tarfn.c_str());
-						return -1;
-					}
-				} else {
-					string temp = Strip_Root_Dir(buf);
-					strcpy(charTarPath, temp.c_str());
-					LOGINFO("tar_append_tree '%s' as '%s'\n", buf, charTarPath);
-					if (tar_append_tree(t, buf, charTarPath, &excl[0]) != 0) {
-						LOGERR("Error appending '%s' to tar archive '%s'\n", buf, tarfn.c_str());
-						return -1;
-					}
-				}
-			} else if (tardir != "/" && (de->d_type == DT_REG || de->d_type == DT_LNK)) {
-				LOGINFO("addFile '%s' including root: %i\n", buf, include_root);
-				if (addFile(buf, include_root) != 0)
-					return -1;
-			}
-			fflush(NULL);
-		}
-		closedir(d);
-	}
-	return 0;
-}
-
-int twrpTar::tarList(bool include_root, std::vector<TarListStruct> *TarList, unsigned thread_id) {
+int twrpTar::tarList(std::vector<TarListStruct> *TarList, unsigned thread_id) {
 	struct stat st;
 	char buf[PATH_MAX];
 	int list_size = TarList->size(), i = 0, archive_count = 0;
 	string temp;
 	char actual_filename[PATH_MAX];
+	char *ptr;
 
-	basefn = tarfn;
-	temp = basefn + "%i%02i";
-	sprintf(actual_filename, temp.c_str(), thread_id, archive_count);
-	tarfn = actual_filename;
+	if (split_archives) {
+		basefn = tarfn;
+		temp = basefn + "%i%02i";
+		sprintf(actual_filename, temp.c_str(), thread_id, archive_count);
+		tarfn = actual_filename;
+		include_root_dir = true;
+	} else {
+		include_root_dir = false;
+	}
+	LOGINFO("Creating tar file '%s'\n", tarfn.c_str());
 	if (createTar() != 0) {
 		LOGERR("Error creating tar '%s' for thread %i\n", tarfn.c_str(), thread_id);
 		return -2;
@@ -808,9 +587,8 @@
 						return -3;
 					}
 					archive_count++;
-					LOGINFO("Splitting thread ID %i into archive %i\n", thread_id, archive_count);
+					gui_print("Splitting thread ID %i into archive %i\n", thread_id, archive_count + 1);
 					if (archive_count > 99) {
-						LOGINFO("BLAH!\n");
 						LOGERR("Too many archives for thread %i\n", thread_id);
 						return -4;
 					}
@@ -824,7 +602,8 @@
 				}
 				Archive_Current_Size += (unsigned long long)(st.st_size);
 			}
-			if (addFile(buf, include_root) != 0) {
+			LOGINFO("addFile '%s' including root: %i\n", buf, include_root_dir);
+			if (addFile(buf, include_root_dir) != 0) {
 				LOGERR("Error adding file '%s' to '%s'\n", buf, tarfn.c_str());
 				return -1;
 			}
@@ -839,23 +618,10 @@
 	return 0;
 }
 
-int twrpTar::create() {
-
-	init_libtar_buffer(0);
-	if (createTar() == -1)
-		return -1;
-	if (tarDirs(false) == -1)
-		return -1;
-	if (closeTar() == -1)
-		return -1;
-	free_libtar_buffer();
-	return 0;
-}
-
 void* twrpTar::createList(void *cookie) {
 
 	twrpTar* threadTar = (twrpTar*) cookie;
-	if (threadTar->tarList(true, threadTar->ItemList, threadTar->thread_id) == -1) {
+	if (threadTar->tarList(threadTar->ItemList, threadTar->thread_id) == -1) {
 		LOGINFO("ERROR tarList for thread ID %i\n", threadTar->thread_id);
 		return (void*)-2;
 	}
@@ -1308,6 +1074,16 @@
 			return -1;
 	}
 	free_libtar_buffer();
+	if (use_compression && !use_encryption) {
+		string gzname = tarfn + ".gz";
+		if (TWFunc::Path_Exists(gzname)) {
+			rename(gzname.c_str(), tarfn.c_str());
+		}
+	}
+	if (TWFunc::Get_File_Size(tarfn) == 0) {
+		LOGERR("Backup file size for '%s' is 0 bytes.\n", tarfn.c_str());
+		return -1;
+	}
 	return 0;
 }
 
diff --git a/twrpTar.hpp b/twrpTar.hpp
index fa3d2ce..17f6959 100644
--- a/twrpTar.hpp
+++ b/twrpTar.hpp
@@ -47,10 +47,10 @@
 	virtual ~twrpTar();
 	int createTarFork();
 	int extractTarFork();
-	int splitArchiveFork();
 	void setexcl(string exclude);
 	void setfn(string fn);
 	void setdir(string dir);
+	void setsize(unsigned long long backup_size);
 	unsigned long long uncompressedSize();
 
 public:
@@ -68,22 +68,19 @@
 	int addFile(string fn, bool include_root);
 	int entryExists(string entry);
 	int closeTar();
-	int create();
-	int Split_Archive();
 	int removeEOT(string tarFile);
 	int extractTar();
-	int tarDirs(bool include_root);
-	int Generate_Multiple_Archives(string Path);
 	string Strip_Root_Dir(string Path);
 	int openTar();
 	int Generate_TarList(string Path, std::vector<TarListStruct> *TarList, unsigned long long *Target_Size, unsigned *thread_id);
 	static void* createList(void *cookie);
 	static void* extractMulti(void *cookie);
-	int tarList(bool include_root, std::vector<TarListStruct> *TarList, unsigned thread_id);
+	int tarList(std::vector<TarListStruct> *TarList, unsigned thread_id);
 
-	int Archive_File_Count;
 	int Archive_Current_Type;
 	unsigned long long Archive_Current_Size;
+	unsigned long long Total_Backup_Size;
+	bool include_root_dir;
 	TAR *t;
 	int fd;
 	pid_t pigz_pid;
@@ -94,7 +91,6 @@
 	string basefn;
 
 	vector <string> tarexclude;
-	vector<string> split;
 
 	std::vector<TarListStruct> *ItemList;
 	int thread_id;