module load: attempt to load modules from /vendor

Use TW_LOAD_VENDOR_MODULES := "module1.ko module2.ko modulen.ko"
in BoardConfig to have TWRP attempt to load kernel modules during
startup. For fastboot ramdisks, TWRP will attempt to load from
the ramdisk from /vendor/lib/modules. You can have the build
system copy the modules to
$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib/modules/1.1
Otherwise in recovery in boot mode, TWRP will attempt the following:
check /lib/modules (ramdisk vendor_boot)
check /lib/modules/N.N (ramdisk vendor_boot)
check /lib/modules/N.N-gki (ramdisk vendor_boot)
check /vendor/lib/modules (ramdisk)
check /vendor/lib/modules/1.1 (ramdisk prebuilt modules)
check /vendor/lib/modules/N.N (vendor mounted)
check /vendor/lib/modules/N.N-gki (vendor mounted)

Change-Id: I2dccf199e37d47cb7a7e79b0e11026d67b4e3186
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index c56e194..0f7ebb3 100755
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -38,6 +38,9 @@
 #include <cctype>
 #include <algorithm>
 #include <selinux/label.h>
+
+#include <android-base/strings.h>
+
 #include "twrp-functions.hpp"
 #include "twcommon.h"
 #include "gui/gui.hpp"
@@ -694,11 +697,13 @@
 	return r;
 }
 
-int TWFunc::copy_file(string src, string dst, int mode) {
-	PartitionManager.Mount_By_Path(src, false);
-	PartitionManager.Mount_By_Path(dst, false);
+int TWFunc::copy_file(string src, string dst, int mode, bool mount_paths) {
+	if (mount_paths) {
+		PartitionManager.Mount_By_Path(src, false);
+		PartitionManager.Mount_By_Path(dst, false);
+	}
 	if (!Path_Exists(src)) {
-		LOGINFO("Path %s does not exist. Unable to copy %s\n", src.c_str(), dst.c_str());
+		LOGINFO("Path %s does not exist. Unable to copy file to %s\n", src.c_str(), dst.c_str());
 		return -1;
 	}
 	std::ifstream srcfile(src.c_str(), ios::binary);
@@ -714,8 +719,10 @@
 
 	srcfile.close();
 	dstfile.close();
-	if (chmod(dst.c_str(), mode) != 0)
+	if (chmod(dst.c_str(), mode) != 0) {
+		LOGERR("Unable to chmod file: %s. Error: %s\n", dst.c_str(), strerror(errno));
 		return -1;
+	}
 	return 0;
 }
 
@@ -745,7 +752,10 @@
 	file.open(fn.c_str(), ios::in);
 
 	if (file.is_open()) {
-		file >> results;
+		std::string line;
+		while (std::getline(file, line)) {
+			results += line;
+		}
 		file.close();
 		return 0;
 	}
@@ -782,18 +792,33 @@
 	return -1;
 }
 
-int TWFunc::write_to_file(const string& fn, const string& line) {
+bool TWFunc::write_to_file(const string& fn, const string& line) {
 	FILE *file;
 	file = fopen(fn.c_str(), "w");
 	if (file != NULL) {
 		fwrite(line.c_str(), line.size(), 1, file);
 		fclose(file);
-		return 0;
+		return true;
 	}
 	LOGINFO("Cannot find file %s\n", fn.c_str());
-	return -1;
+	return false;
 }
 
+bool TWFunc::write_to_file(const string& fn, const std::vector<string> lines) {
+	FILE *file;
+	file = fopen(fn.c_str(), "a+");
+	if (file != NULL) {
+		for (auto&& line: lines) {
+			fwrite(line.c_str(), line.size(), 1, file);
+			fwrite("\n", sizeof(char), 1, file);
+		}
+		fclose(file);
+		return true;
+	}
+	return false;
+}
+
+
 bool TWFunc::Try_Decrypting_Backup(string Restore_Path, string Password) {
 	DIR* d;
 
@@ -1086,7 +1111,7 @@
 			TWFunc::write_to_file(secondary_brightness_file, brightness_value);
 		}
 	}
-	return result;
+	return result ? 0 : -1;
 }
 
 bool TWFunc::Toggle_MTP(bool enable) {