Create a TWRP Disk Usage Class to retain state about a directory and whether we should skip it in other classes like twrpTar.
Moved Get_Folder_Size to this new class.

Change-Id: If0a0220f900eb109581f2eeaf7b76e3f7d6886f1
diff --git a/Android.mk b/Android.mk
index d96e53f..85f8072 100644
--- a/Android.mk
+++ b/Android.mk
@@ -20,6 +20,7 @@
     twrp.cpp \
     fixPermissions.cpp \
     twrpTar.cpp \
+	twrpDU.cpp \
     twrpDigest.cpp \
 
 LOCAL_SRC_FILES += \
diff --git a/partition.cpp b/partition.cpp
index 061a3e1..31b1bfd 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -1,5 +1,5 @@
 /*
-	Copyright 2012 bigbiff/Dees_Troy TeamWin
+	Copyright 2013 TeamWin
 	This file is part of TWRP/TeamWin Recovery Project.
 
 	TWRP is free software: you can redistribute it and/or modify
@@ -39,6 +39,7 @@
 #include "twrp-functions.hpp"
 #include "twrpDigest.hpp"
 #include "twrpTar.hpp"
+#include "twrpDU.hpp"
 extern "C" {
 	#include "mtdutils/mtdutils.h"
 	#include "mtdutils/mounts.h"
@@ -811,7 +812,7 @@
 
 			sscanf(line, "%s %lx %*lx %*lu %s", label, &size, device);
 
-			// Skip header, annotation  and blank lines
+			// Skip header, annotation	and blank lines
 			if ((strncmp(device, "/dev/", 5) != 0) || (strlen(line) < 8))
 				continue;
 
@@ -1514,7 +1515,7 @@
 	if (d != NULL) {
 		struct dirent* de;
 		while ((de = readdir(d)) != NULL) {
-			if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)   continue;
+			if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)	 continue;
 			// 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.
@@ -1555,7 +1556,10 @@
 	DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
 	tar.use_compression = use_compression;
 	//exclude Google Music Cache
-	tar.setexcl("/data/data/com.google.android.music/files");
+	vector<string> excludedirs = du.get_absolute_dirs();
+	for (int i = 0; i < excludedirs.size(); ++i) {
+		tar.setexcl(excludedirs.at(i));
+	}
 #ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
 	DataManager::GetValue("tw_encrypt_backup", use_encryption);
 	if (use_encryption && Can_Encrypt_Backup) {
@@ -1772,16 +1776,12 @@
 	if (Has_Data_Media) {
 		if (Mount(Display_Error)) {
 			unsigned long long data_media_used, actual_data;
-			Used = TWFunc::Get_Folder_Size("/data", Display_Error);
-			data_media_used = TWFunc::Get_Folder_Size("/data/media", Display_Error);
-			actual_data = Used - data_media_used;
-			Backup_Size = actual_data;
-			int bak = (int)(Backup_Size / 1048576LLU);
-			int total = (int)(Size / 1048576LLU);
-			int us = (int)(Used / 1048576LLU);
+			du.add_relative_dir("media");
+			Used = du.Get_Folder_Size("/data");
+			Backup_Size = Used;
+			int bak = (int)(Used / 1048576LLU);
 			int fre = (int)(Free / 1048576LLU);
-			int datmed = (int)(data_media_used / 1048576LLU);
-			LOGINFO("Data backup size is %iMB, size: %iMB, used: %iMB, free: %iMB, in data/media: %iMB.\n", bak, total, us, fre, datmed);
+			LOGINFO("Data backup size is %iMB, free: %iMB.\n", bak, fre);
 		} else {
 			if (!Was_Already_Mounted)
 				UnMount(false);
@@ -1789,7 +1789,7 @@
 		}
 	} else if (Has_Android_Secure) {
 		if (Mount(Display_Error))
-			Backup_Size = TWFunc::Get_Folder_Size(Backup_Path, Display_Error);
+			Backup_Size = du.Get_Folder_Size(Backup_Path);
 		else {
 			if (!Was_Already_Mounted)
 				UnMount(false);
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 7634ff0..da11e8d 100644
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -36,6 +36,7 @@
 #include "twrp-functions.hpp"
 #include "fixPermissions.hpp"
 #include "twrpDigest.hpp"
+#include "twrpDU.hpp"
 
 #ifdef TW_INCLUDE_CRYPTO
 	#ifdef TW_INCLUDE_JB_CRYPTO
@@ -46,6 +47,9 @@
 	#include "cutils/properties.h"
 #endif
 
+TWPartitionManager::TWPartitionManager(void) {
+}
+
 int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) {
 	FILE *fstabFile;
 	char fstab_line[MAX_FSTAB_LINE_LENGTH];
@@ -772,7 +776,7 @@
 
 	time(&total_stop);
 	int total_time = (int) difftime(total_stop, total_start);
-	unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
+	uint64_t actual_backup_size = du.Get_Folder_Size(Full_Backup_Path);
     actual_backup_size /= (1024LLU * 1024LLU);
 
 	int prev_img_bps, use_compression;
diff --git a/partitions.hpp b/partitions.hpp
index 62f95d0..287da62 100644
--- a/partitions.hpp
+++ b/partitions.hpp
@@ -21,6 +21,7 @@
 
 #include <vector>
 #include <string>
+#include "twrpDU.hpp"
 
 #define MAX_FSTAB_LINE_LENGTH 2048
 
@@ -162,7 +163,7 @@
 class TWPartitionManager
 {
 public:
-	TWPartitionManager() {}
+	TWPartitionManager();													  // Constructor for TWRPartionManager
 	~TWPartitionManager() {}
 
 public:
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index f0c8cd4..e172f3d 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -206,39 +206,6 @@
 	return true;
 }
 
-unsigned long long TWFunc::Get_Folder_Size(const string& Path, bool Display_Error) {
-	DIR* d;
-	struct dirent* de;
-	struct stat st;
-	unsigned long long dusize = 0;
-	unsigned long long dutemp = 0;
-
-	d = opendir(Path.c_str());
-	if (d == NULL)
-	{
-		LOGERR("error opening '%s'\n", Path.c_str());
-		LOGERR("error: %s\n", strerror(errno));
-		return 0;
-	}
-
-	while ((de = readdir(d)) != NULL)
-	{
-		if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0 && strcmp(de->d_name, "lost+found") != 0)
-		{
-			dutemp = Get_Folder_Size((Path + "/" + de->d_name), Display_Error);
-			dusize += dutemp;
-			dutemp = 0;
-		}
-		else if (de->d_type == DT_REG)
-		{
-			stat((Path + "/" + de->d_name).c_str(), &st);
-			dusize += (unsigned long long)(st.st_size);
-		}
-	}
-	closedir(d);
-	return dusize;
-}
-
 bool TWFunc::Path_Exists(string Path) {
 	// Check to see if the Path exists
 	struct stat st;
diff --git a/twrp-functions.hpp b/twrp-functions.hpp
index b580fe4..1050f56 100644
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -46,7 +46,6 @@
 	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 unsigned long long Get_Folder_Size(const string& Path, bool Display_Error); // Gets the size of a folder and all of its subfolders using dirent and stat
 	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
diff --git a/twrp.cpp b/twrp.cpp
index 3a8dd82..3e56af2 100644
--- a/twrp.cpp
+++ b/twrp.cpp
@@ -1,19 +1,18 @@
 /*
-        Copyright 2013 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.
+ccdd
+		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.
+		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/>.
+		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>
@@ -45,6 +44,7 @@
 #include "partitions.hpp"
 #include "openrecoveryscript.hpp"
 #include "variables.h"
+#include "twrpDU.hpp"
 
 #ifdef HAVE_SELINUX
 #include "selinux/label.h"
@@ -53,6 +53,7 @@
 
 TWPartitionManager PartitionManager;
 int Log_Offset;
+twrpDU du;
 
 static void Print_Prop(const char *key, const char *name, void *cookie) {
 	printf("%s=%s\n", key, name);
@@ -124,7 +125,7 @@
 		char *contexts = NULL;
 		lgetfilecon("/sbin/teamwin", &contexts);
 		if (!contexts) {
-		    gui_print("Kernel does not have support for reading SELinux contexts.\n");
+			gui_print("Kernel does not have support for reading SELinux contexts.\n");
 		} else {
 			free(contexts);
 			gui_print("Full SELinux support is present.\n");
diff --git a/twrpDU.cpp b/twrpDU.cpp
new file mode 100644
index 0000000..66c8031
--- /dev/null
+++ b/twrpDU.cpp
@@ -0,0 +1,107 @@
+/*
+		Copyright 2013 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 <string>
+#include <vector>
+#include "twrpDU.hpp"
+
+using namespace std;
+
+twrpDU::twrpDU() {
+		add_relative_dir(".");
+		add_relative_dir("..");
+		add_relative_dir("lost_found");
+		add_absolute_dir("/data/data/com.google.android.music/files");
+		parent = "";
+}
+
+void twrpDU::add_relative_dir(string dir) {
+	relativedir.push_back(dir);
+}
+
+void twrpDU::add_absolute_dir(string dir) {
+	absolutedir.push_back(dir);
+}
+
+vector<string> twrpDU::get_absolute_dirs(void) {
+	return absolutedir;
+}
+
+uint64_t twrpDU::Get_Folder_Size(const string& Path) {
+	DIR* d;
+	struct dirent* de;
+	struct stat st;
+	unsigned long long dusize = 0;
+	unsigned long long dutemp = 0;
+
+	parent = Path.substr(0, Path.find_last_of('/'));
+
+	d = opendir(Path.c_str());
+	if (d == NULL) {
+		LOGERR("error opening '%s'\n", Path.c_str());
+		LOGERR("error: %s\n", strerror(errno));
+		return 0;
+	}
+
+	while ((de = readdir(d)) != NULL)
+	{
+		bool skip_dir = false;
+		if (de->d_type == DT_DIR) {
+			string dir = de->d_name;
+			skip_dir = check_skip_dirs(dir);
+		}
+		if (de->d_type == DT_DIR && !skip_dir) {
+			dutemp = Get_Folder_Size((Path + "/" + de->d_name));
+			dusize += dutemp;
+			dutemp = 0;
+		}
+		else if (de->d_type == DT_REG) {
+			stat((Path + "/" + de->d_name).c_str(), &st);
+			dusize += (uint64_t)(st.st_size);
+		}
+	}
+	closedir(d);
+	return dusize;
+}
+
+bool twrpDU::check_skip_dirs(string& dir) {
+	bool result = false;
+	for (int i = 0; i < relativedir.size(); ++i) {
+		if (dir == relativedir.at(i)) {
+			result = true;
+			break;
+		}
+	}
+	for (int i = 0; i < absolutedir.size(); ++i) {
+		//string absdir = parent + dir;
+		if (dir == absolutedir.at(i)) {
+			result = true;
+			break;
+		}
+	}
+	return result;
+}
diff --git a/twrpDU.hpp b/twrpDU.hpp
new file mode 100644
index 0000000..04527cd
--- /dev/null
+++ b/twrpDU.hpp
@@ -0,0 +1,52 @@
+/*
+        Copyright 2013 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/>.
+*/
+
+#ifndef TWRPDU_HPP
+#define TWRPDU_HPP
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fstream>
+#include <string>
+#include <vector>
+#include "twcommon.h"
+
+using namespace std;
+
+class twrpDU {
+
+public:
+	twrpDU();
+	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
+	vector<string> get_absolute_dirs(void);
+private:
+	vector<string> absolutedir;
+	vector<string> relativedir;
+	string parent;
+};
+
+extern twrpDU du;
+#endif
diff --git a/twrpTar.cpp b/twrpTar.cpp
index eba482e..48d529b 100644
--- a/twrpTar.cpp
+++ b/twrpTar.cpp
@@ -1,5 +1,5 @@
 /*
-	Copyright 2012 bigbiff/Dees_Troy TeamWin
+	Copyright 2013 TeamWin
 	This file is part of TWRP/TeamWin Recovery Project.
 
 	TWRP is free software: you can redistribute it and/or modify
@@ -115,7 +115,10 @@
 					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 && strcmp(de->d_name, "lost+found") != 0) {
+				bool skip_dir = false;
+				string dir(de->d_name);
+				skip_dir = du.check_skip_dirs(dir);
+				if (de->d_type == DT_DIR && !skip_dir) {
 					item_len = strlen(de->d_name);
 					if (userdata_encryption && ((item_len >= 3 && strncmp(de->d_name, "app", 3) == 0) || (item_len >= 6 && strncmp(de->d_name, "dalvik", 6) == 0))) {
 						if (Generate_TarList(FileName, &RegularList, &target_size, &regular_thread_id) < 0) {
@@ -123,9 +126,9 @@
 							closedir(d);
 							_exit(-1);
 						}
-						regular_size += TWFunc::Get_Folder_Size(FileName, false);
+						regular_size += du.Get_Folder_Size(FileName);
 					} else {
-						encrypt_size += TWFunc::Get_Folder_Size(FileName, false);
+						encrypt_size += du.Get_Folder_Size(FileName);
 					}
 				} else if (de->d_type == DT_REG) {
 					stat(FileName.c_str(), &st);
@@ -159,7 +162,10 @@
 					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 && strcmp(de->d_name, "lost+found") != 0) {
+				bool skip_dir = false;
+				string dir(de->d_name);
+				skip_dir = du.check_skip_dirs(dir);
+				if (de->d_type == DT_DIR && !skip_dir) {
 					item_len = strlen(de->d_name);
 					if (userdata_encryption && ((item_len >= 3 && strncmp(de->d_name, "app", 3) == 0) || (item_len >= 6 && strncmp(de->d_name, "dalvik", 6) == 0))) {
 						// Do nothing, we added these to RegularList earlier
@@ -472,7 +478,10 @@
 			continue;
 		TarItem.fn = FileName;
 		TarItem.thread_id = *thread_id;
-		if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0 && strcmp(de->d_name, "lost+found") != 0) {
+		bool skip_dir = false;
+		string dir(de->d_name);
+		skip_dir = du.check_skip_dirs(dir);
+		if (de->d_type == DT_DIR && !skip_dir) {
 			TarList->push_back(TarItem);
 			if (Generate_TarList(FileName, TarList, Target_Size, thread_id) < 0)
 				return -1;
@@ -535,7 +544,7 @@
 			continue;
 		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);
+			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());
@@ -699,10 +708,16 @@
 		}
 		struct dirent* de;
 		while ((de = readdir(d)) != NULL) {
+		    bool skip_dir = false;
 #ifdef RECOVERY_SDCARD_ON_DATA
-			if ((tardir == "/data" || tardir == "/data/") && strcmp(de->d_name, "media") == 0) continue;
+			du.add_absolute_dir("/data/media");
+			string dir(tardir + "/" + de->d_name);
+		    skip_dir = du.check_skip_dirs(dir);
+			if (skip_dir) continue;
 #endif
-			if (de->d_type == DT_BLK || de->d_type == DT_CHR || strcmp(de->d_name, "..") == 0 || strcmp(de->d_name, "lost+found") == 0)
+			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
diff --git a/twrpTar.hpp b/twrpTar.hpp
index 9128ba0..fa3d2ce 100644
--- a/twrpTar.hpp
+++ b/twrpTar.hpp
@@ -27,6 +27,7 @@
 #include <fstream>
 #include <string>
 #include <vector>
+#include "twrpDU.hpp"
 
 using namespace std;