Merge "Fix fail over to vfat from exfat" into twrp2.4
diff --git a/Android.mk b/Android.mk
index 3cfd1fb..de25ff2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -188,6 +188,9 @@
 ifeq ($(TW_FORCE_CPUINFO_FOR_DEVICE_ID), true)
     LOCAL_CFLAGS += -DTW_FORCE_CPUINFO_FOR_DEVICE_ID
 endif
+ifeq ($(TW_NO_EXFAT_FUSE), true)
+    LOCAL_CFLAGS += -DTW_NO_EXFAT_FUSE
+endif
 ifeq ($(TW_INCLUDE_CRYPTO), true)
     LOCAL_CFLAGS += -DTW_INCLUDE_CRYPTO
     LOCAL_CFLAGS += -DCRYPTO_FS_TYPE=\"$(TW_CRYPTO_FS_TYPE)\"
diff --git a/partition.cpp b/partition.cpp
index 16bc5dc..f7e2ef4 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -669,6 +669,8 @@
 }
 
 bool TWPartition::Mount(bool Display_Error) {
+	int exfat_mounted = 0;
+
 	if (Is_Mounted()) {
 		return true;
 	} else if (!Can_Be_Mounted) {
@@ -679,6 +681,23 @@
 
 	// Check the current file system before mounting
 	Check_FS_Type();
+	if (Current_File_System == "exfat" && TWFunc::Path_Exists("/sbin/exfat-fuse")) {
+		string cmd = "/sbin/exfat-fuse " + Actual_Block_Device + " " + Mount_Point;
+		LOGI("cmd: %s\n", cmd.c_str());
+		string result;
+		if (TWFunc::Exec_Cmd(cmd, result) != 0) {
+			LOGI("exfat-fuse failed to mount with result '%s', trying vfat\n", result.c_str());
+			Current_File_System = "vfat";
+		} else {
+#ifdef TW_NO_EXFAT_FUSE
+			UnMount(false);
+			// We'll let the kernel handle it but using exfat-fuse to detect if the file system is actually exfat
+			// Some kernels let us mount vfat as exfat which doesn't work out too well
+#else
+			exfat_mounted = 1;
+#endif
+		}
+	}
 	if (Fstab_File_System == "yaffs2") {
 		// mount an MTD partition as a YAFFS2 filesystem.
 		mtd_scan_partitions();
@@ -697,46 +716,54 @@
 			return false;
 		} else
 			return true;
-	} else if (Current_File_System == "exfat" && TWFunc::Path_Exists("/sbin/exfat-fuse")) {
-		string cmd = "/sbin/exfat-fuse " + Actual_Block_Device + " " + Mount_Point;
-		LOGI("cmd: %s\n", cmd.c_str());
-		string result;
-		if (TWFunc::Exec_Cmd(cmd, result) != 0) 
-			return false;
-	} else if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
-		if (Display_Error)
-			LOGE("Unable to mount '%s'\n", Mount_Point.c_str());
-		else
-			LOGI("Unable to mount '%s'\n", Mount_Point.c_str());
-		LOGI("Actual block device: '%s', current file system: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str());
-		return false;
-	} else {
-#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
-		string MetaEcfsFile = EXPAND(TW_EXTERNAL_STORAGE_PATH);
-		MetaEcfsFile += "/.MetaEcfsFile";
-		if (EcryptFS_Password.size() > 0 && PartitionManager.Mount_By_Path("/data", false) && TWFunc::Path_Exists(MetaEcfsFile)) {
-			if (mount_ecryptfs_drive(EcryptFS_Password.c_str(), Mount_Point.c_str(), Mount_Point.c_str(), 0) != 0) {
+	} else if (!exfat_mounted && mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
+#ifdef TW_NO_EXFAT_FUSE
+		if (Current_File_System == "exfat") {
+			LOGI("Mounting exfat failed, trying vfat...\n");
+			if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), "vfat", 0, NULL) != 0) {
 				if (Display_Error)
-					LOGE("Unable to mount ecryptfs for '%s'\n", Mount_Point.c_str());
+					LOGE("Unable to mount '%s'\n", Mount_Point.c_str());
 				else
-					LOGI("Unable to mount ecryptfs for '%s'\n", Mount_Point.c_str());
-			} else {
-				LOGI("Successfully mounted ecryptfs for '%s'\n", Mount_Point.c_str());
-				Is_Decrypted = true;
+					LOGI("Unable to mount '%s'\n", Mount_Point.c_str());
+				LOGI("Actual block device: '%s', current file system: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str());
+				return false;
 			}
 		} else {
-			Is_Decrypted = false;
+#endif
+			if (Display_Error)
+				LOGE("Unable to mount '%s'\n", Mount_Point.c_str());
+			else
+				LOGI("Unable to mount '%s'\n", Mount_Point.c_str());
+			LOGI("Actual block device: '%s', current file system: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str());
+			return false;
+#ifdef TW_NO_EXFAT_FUSE
 		}
 #endif
-		if (Removable)
-			Update_Size(Display_Error);
-
-		if (!Symlink_Mount_Point.empty()) {
-			string Command, Result;
-			Command = "mount '" + Symlink_Path + "' '" + Symlink_Mount_Point + "'";
-			TWFunc::Exec_Cmd(Command, Result);
+	}
+#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
+	string MetaEcfsFile = EXPAND(TW_EXTERNAL_STORAGE_PATH);
+	MetaEcfsFile += "/.MetaEcfsFile";
+	if (EcryptFS_Password.size() > 0 && PartitionManager.Mount_By_Path("/data", false) && TWFunc::Path_Exists(MetaEcfsFile)) {
+		if (mount_ecryptfs_drive(EcryptFS_Password.c_str(), Mount_Point.c_str(), Mount_Point.c_str(), 0) != 0) {
+			if (Display_Error)
+				LOGE("Unable to mount ecryptfs for '%s'\n", Mount_Point.c_str());
+			else
+				LOGI("Unable to mount ecryptfs for '%s'\n", Mount_Point.c_str());
+		} else {
+			LOGI("Successfully mounted ecryptfs for '%s'\n", Mount_Point.c_str());
+			Is_Decrypted = true;
 		}
-		return true;
+	} else {
+		Is_Decrypted = false;
+	}
+#endif
+	if (Removable)
+		Update_Size(Display_Error);
+
+	if (!Symlink_Mount_Point.empty()) {
+		string Command, Result;
+		Command = "mount '" + Symlink_Path + "' '" + Symlink_Mount_Point + "'";
+		TWFunc::Exec_Cmd(Command, Result);
 	}
 	return true;
 }
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 5230810..19efd42 100644
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -485,8 +485,7 @@
 	ui_print(" * Generating md5...\n");
 
 	if (TWFunc::Path_Exists(Full_File)) {
-		command = "md5sum " + Backup_Filename + " > " + Backup_Filename + ".md5";
-		chdir(Backup_Folder.c_str());
+		command = "cd '" + Backup_Folder + "' && md5sum '" + Backup_Filename + "' > '" + Backup_Filename + ".md5'";
 		if (TWFunc::Exec_Cmd(command, result) == 0) {
 			ui_print(" * MD5 Created.\n");
 			return true;
@@ -503,8 +502,7 @@
 			intToStr << index;
 			ostringstream fn;
 			fn << setw(3) << setfill('0') << intToStr.str();
-			command = "md5sum " + Backup_Filename + fn.str() + " >"  + Backup_Filename + fn.str() + ".md5";
-			chdir(Backup_Folder.c_str());
+			command = "cd '" + Backup_Folder + "' && md5sum '" + Backup_Filename + fn.str() + "' > '"  + Backup_Filename + fn.str() + ".md5'";
 			if (TWFunc::Exec_Cmd(command, result) != 0) {
 				ui_print(" * MD5 Error.\n");
 				return false;
@@ -887,7 +885,9 @@
 	Update_System_Details();
 	UnMount_Main_Partitions();
 	ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
-    	return true;
+	string backup_log = Full_Backup_Path + "recovery.log";
+	TWFunc::copy_file("/tmp/recovery.log", backup_log, 0644);
+	return true;
 }
 
 bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name, int partition_count) {
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index 0c4471a..4a5dec2 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -62,8 +62,7 @@
 	if (Path_Exists(MD5_File)) {
 		DirPath = Get_Path(File);
 		MD5_File = Get_Filename(MD5_File);
-		chdir(DirPath.c_str());
-		Command = "/sbin/busybox md5sum -c " + MD5_File;
+		Command = "cd '" + DirPath + "' && /sbin/busybox md5sum -c '" + MD5_File + "'";
 		Exec_Cmd(Command, result);
 		pos = result.find(":");
 		if (pos != string::npos) {