Support v2 fstab format

Auto detect and support both the v1 and v2 fstab formats
Support putting TWRP style flags in a separate /etc/twrp.flags file

twrp.flags format is the same as twrp.fstab (v1 with TWRP flags)

Support using a wildcard in a block device and find all partitions:
/usb-otg vfat /dev/block/sda*

Support using sysfs entries (voldmanaged) and read uevents and scan for
wildcard partitions from uevent data. (twvold?)

May not be complete for some of the newer flags found in fstabs in newer
build trees and there is a slim chance of a crash if the user removes a
removable device while TWRP is performing actions. May need to add some
kind of mutex to prevent the 2 threads from causing this crash. We need
to start somewhere though and this change is pretty innocuous when not
using a v2 fstab.

Change-Id: I617d97c7db332cbe671a9d2b8ad98b3d9c4f03cc
diff --git a/gui/action.cpp b/gui/action.cpp
index 039c4ef..3d497ca 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -1,4 +1,4 @@
-/*update
+/*
 	Copyright 2013 bigbiff/Dees_Troy TeamWin
 	This file is part of TWRP/TeamWin Recovery Project.
 
diff --git a/gui/gui.cpp b/gui/gui.cpp
index a70dadf..a270e36 100644
--- a/gui/gui.cpp
+++ b/gui/gui.cpp
@@ -33,7 +33,6 @@
 #include <sys/mount.h>
 #include <time.h>
 #include <unistd.h>
-#include <stdlib.h>
 
 extern "C"
 {
@@ -79,6 +78,8 @@
 int g_pty_fd = -1;  // set by terminal on init
 void terminal_pty_read();
 
+int select_fd = 0;
+
 static int gRecorder = -1;
 
 extern "C" void gr_write_frame_to_file(int fd);
@@ -395,9 +396,18 @@
 	}
 }
 
+void set_select_fd() {
+	select_fd = ors_read_fd + 1;
+	if (g_pty_fd >= select_fd)
+		select_fd = g_pty_fd + 1;
+	if (PartitionManager.uevent_pfd.fd >= select_fd)
+		select_fd = PartitionManager.uevent_pfd.fd + 1;
+}
+
 static void setup_ors_command()
 {
 	ors_read_fd = -1;
+	set_select_fd();
 
 	unlink(ORS_INPUT_FILE);
 	if (mkfifo(ORS_INPUT_FILE, 06660) != 0) {
@@ -417,6 +427,7 @@
 		unlink(ORS_INPUT_FILE);
 		unlink(ORS_OUTPUT_FILE);
 	}
+	set_select_fd();
 }
 
 // callback called after a CLI command was executed
@@ -448,6 +459,7 @@
 		if (!orsout) {
 			close(ors_read_fd);
 			ors_read_fd = -1;
+			set_select_fd();
 			LOGINFO("Unable to fopen %s\n", ORS_OUTPUT_FILE);
 			unlink(ORS_INPUT_FILE);
 			unlink(ORS_OUTPUT_FILE);
@@ -554,29 +566,30 @@
 	for (;;)
 	{
 		loopTimer(input_timeout_ms);
+		FD_ZERO(&fdset);
+		timeout.tv_sec = 0;
+		timeout.tv_usec = 1;
 		if (g_pty_fd > 0) {
-			// TODO: this is not nice, we should have one central select for input, pty, and ors
-			FD_ZERO(&fdset);
 			FD_SET(g_pty_fd, &fdset);
-			timeout.tv_sec = 0;
-			timeout.tv_usec = 1;
-			has_data = select(g_pty_fd+1, &fdset, NULL, NULL, &timeout);
-			if (has_data > 0) {
-				terminal_pty_read();
-			}
+		}
+		if (PartitionManager.uevent_pfd.fd > 0) {
+			FD_SET(PartitionManager.uevent_pfd.fd, &fdset);
 		}
 #ifndef TW_OEM_BUILD
 		if (ors_read_fd > 0 && !orsout) { // orsout is non-NULL if a command is still running
-			FD_ZERO(&fdset);
 			FD_SET(ors_read_fd, &fdset);
-			timeout.tv_sec = 0;
-			timeout.tv_usec = 1;
-			has_data = select(ors_read_fd+1, &fdset, NULL, NULL, &timeout);
-			if (has_data > 0) {
-				ors_command_read();
-			}
 		}
 #endif
+		// TODO: combine this select with the poll done by input handling
+		has_data = select(select_fd, &fdset, NULL, NULL, &timeout);
+		if (has_data > 0) {
+			if (g_pty_fd > 0 && FD_ISSET(g_pty_fd, &fdset))
+				terminal_pty_read();
+			if (PartitionManager.uevent_pfd.fd > 0 && FD_ISSET(PartitionManager.uevent_pfd.fd, &fdset))
+				PartitionManager.read_uevent();
+			if (ors_read_fd > 0 && !orsout && FD_ISSET(ors_read_fd, &fdset))
+				ors_command_read();
+		}
 
 		if (!gForceRender.get_value())
 		{
@@ -636,6 +649,7 @@
 	if (ors_read_fd > 0)
 		close(ors_read_fd);
 	ors_read_fd = -1;
+	set_select_fd();
 	gGuiRunning = 0;
 	return 0;
 }
diff --git a/gui/gui.hpp b/gui/gui.hpp
index afcd9b0..d5b9553 100644
--- a/gui/gui.hpp
+++ b/gui/gui.hpp
@@ -21,6 +21,8 @@
 
 #include "twmsg.h"
 
+void set_select_fd();
+
 void gui_msg(const char* text);
 void gui_warn(const char* text);
 void gui_err(const char* text);
diff --git a/gui/terminal.cpp b/gui/terminal.cpp
index 1744788..65ad2c0 100644
--- a/gui/terminal.cpp
+++ b/gui/terminal.cpp
@@ -34,6 +34,7 @@
 #include "../twcommon.h"
 }
 #include "../minuitwrp/minui.h"
+#include "gui.hpp"
 
 #include "rapidxml.hpp"
 #include "objects.hpp"
@@ -83,6 +84,7 @@
 			// and write it to the terminal
 			// this currently works through gui.cpp calling terminal_pty_read below
 			g_pty_fd = fdMaster;
+			set_select_fd();
 			return true;
 		}
 		else {
@@ -174,6 +176,7 @@
 		}
 		close(fdMaster);
 		g_pty_fd = fdMaster = -1;
+		set_select_fd();
 		int status;
 		waitpid(pid, &status, WNOHANG); // avoid zombies but don't hang if the child is still alive and we got here due to some error
 		pid = 0;
diff --git a/gui/theme/common/languages/en.xml b/gui/theme/common/languages/en.xml
index 8a1be18..23beb40 100644
--- a/gui/theme/common/languages/en.xml
+++ b/gui/theme/common/languages/en.xml
@@ -30,6 +30,7 @@
 		<string name="sdext">SD-EXT</string>
 		<string name="adopted_data">Adopted Data</string>
 		<string name="adopted_storage">Adopted Storage</string>
+		<string name="autostorage">Storage</string>
 
 		<!-- GUI XML strings -->
 		<string name="twrp_header">Team Win Recovery Project</string>