Rewrite FS fstab flag processing

* If 'ro' fsflag detected, set Mount_Read_Only = true
* Only output human readable Mount_Options to log
* Match fsflags identically (not just first n chars) since there are
  no fs_flags which take arguments
* Match new processing method introduced in TW fstab flag processing

Change-Id: Iefdb76016be90a131b0d627d0cd3f18d2eb1a008
diff --git a/partition.cpp b/partition.cpp
index 07d7171..bdc8dcb 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -82,7 +82,7 @@
 	unsigned flag;
 };
 
-static struct flag_list mount_flags[] = {
+const struct flag_list mount_flags[] = {
 	{ "noatime",    MS_NOATIME },
 	{ "noexec",     MS_NOEXEC },
 	{ "nosuid",     MS_NOSUID },
@@ -512,36 +512,40 @@
 	return true;
 }
 
-bool TWPartition::Process_FS_Flags(string& Options, int& Flags) {
-	int i;
-	char *p;
-	char *savep;
-	char fs_options[250];
+void TWPartition::Process_FS_Flags(const char *str) {
+	char *options = strdup(str);
+	char *ptr, *savep;
 
-	strlcpy(fs_options, Options.c_str(), sizeof(fs_options));
-	Options = "";
+	Mount_Options = "";
 
-	p = strtok_r(fs_options, ",", &savep);
-	while (p) {
-		/* Look for the flag "p" in the flag list "fl"
-		* If not found, the loop exits with fl[i].name being null.
-		*/
-		for (i = 0; mount_flags[i].name; i++) {
-			if (strncmp(p, mount_flags[i].name, strlen(mount_flags[i].name)) == 0) {
-				Flags |= mount_flags[i].flag;
+	// Avoid issues with potentially nested strtok by using strtok_r
+	ptr = strtok_r(options, ",", &savep);
+	while (ptr) {
+		const struct flag_list* mount_flag = mount_flags;
+
+		for (; mount_flag->name; mount_flag++) {
+			// mount_flags are never postfixed by '=',
+			// so only match identical strings (including length)
+			if (strcmp(ptr, mount_flag->name) == 0) {
+				Mount_Flags |= mount_flag->flag;
 				break;
 			}
 		}
 
-		if (!mount_flags[i].name) {
-			if (Options.size() > 0)
-				Options += ",";
-			Options += p;
-		}
-		p = strtok_r(NULL, ",", &savep);
-	}
+		if (mount_flag->flag == MS_RDONLY)
+			Mount_Read_Only = true;
 
-	return true;
+		if (mount_flag->name != 0) {
+			if (!Mount_Options.empty())
+				Mount_Options += ",";
+			Mount_Options += mount_flag->name;
+		} else {
+			LOGINFO("Unhandled mount flag: '%s'\n", ptr);
+		}
+
+		ptr = strtok_r(NULL, ",", &savep);
+	}
+	free(options);
 }
 
 void TWPartition::Apply_TW_Flag(const unsigned flag, const char* str, const bool val) {
@@ -578,8 +582,7 @@
 			Can_Flash_Img = val;
 			break;
 		case TWFLAG_FSFLAGS:
-			Mount_Options = str;
-			Process_FS_Flags(Mount_Options, Mount_Flags);
+			Process_FS_Flags(str);
 			break;
 		case TWFLAG_IGNOREBLKID:
 			Ignore_Blkid = val;