summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--data.cpp6
-rw-r--r--etc/init.rc1
-rw-r--r--gui/action.cpp22
-rw-r--r--partition.cpp259
-rw-r--r--partitionmanager.cpp242
-rw-r--r--partitions.hpp12
-rw-r--r--recovery.cpp5
-rw-r--r--roots.cpp3
8 files changed, 410 insertions, 140 deletions
diff --git a/data.cpp b/data.cpp
index 92e2e413f..296843546 100644
--- a/data.cpp
+++ b/data.cpp
@@ -296,14 +296,8 @@ int DataManager::SetValue(const string varName, int value, int persist /* = 0 */
if (GetIntValue(TW_HAS_DUAL_STORAGE) == 1) {
if (value == 0) {
str = GetStrValue(TW_INTERNAL_PATH);
- if (GetIntValue(TW_HAS_DATA_MEDIA) == 1) {
- LOGE("TODO: Fix storage size code!\n"); //SetValue(TW_STORAGE_FREE_SIZE, (int)((dat.sze - dat.used) / 1048576LLU));
- } else {
- LOGE("TODO: Fix storage size code!\n"); //SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcint.sze - sdcint.used) / 1048576LLU));
- }
} else {
str = GetStrValue(TW_EXTERNAL_PATH);
- LOGE("TODO: Fix storage size code!\n"); //SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcext.sze - sdcext.used) / 1048576LLU));
}
} else if (GetIntValue(TW_HAS_INTERNAL) == 1)
str = GetStrValue(TW_INTERNAL_PATH);
diff --git a/etc/init.rc b/etc/init.rc
index a6f2f909e..e26027a13 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -10,7 +10,6 @@ on init
symlink /system/etc /etc
- mkdir /emmc
mkdir /system
mkdir /data
mkdir /cache
diff --git a/gui/action.cpp b/gui/action.cpp
index db4c9c415..aee56849f 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -416,14 +416,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
{
string cmd;
if (arg == "EXTERNAL")
- cmd = "mount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT);
+ PartitionManager.Mount_By_Path(DataManager::GetStrValue(TW_EXTERNAL_MOUNT), true);
else if (arg == "INTERNAL")
- cmd = "mount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT);
+ PartitionManager.Mount_By_Path(DataManager::GetStrValue(TW_INTERNAL_MOUNT), true);
else
- cmd = "mount " + arg;
- __system(cmd.c_str());
- if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1)
- __system("mount /datadata");
+ PartitionManager.Mount_By_Path(arg, true);
} else
ui_print("Simulating actions...\n");
return 0;
@@ -443,16 +440,11 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
{
string cmd;
if (arg == "EXTERNAL")
- cmd = "umount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT);
+ PartitionManager.UnMount_By_Path(DataManager::GetStrValue(TW_EXTERNAL_MOUNT), true);
else if (arg == "INTERNAL")
- cmd = "umount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT);
- else if (DataManager::GetIntValue(TW_DONT_UNMOUNT_SYSTEM) == 1 && (arg == "system" || arg == "/system"))
- return 0;
+ PartitionManager.UnMount_By_Path(DataManager::GetStrValue(TW_INTERNAL_MOUNT), true);
else
- cmd = "umount " + arg;
- __system(cmd.c_str());
- if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1)
- __system("umount /datadata");
+ PartitionManager.UnMount_By_Path(arg, true);
} else
ui_print("Simulating actions...\n");
return 0;
@@ -549,7 +541,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
} else if (arg == "external") {
DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 1);
}
- if (PartitionManager.Mount_Settings_Storage(true)) {
+ if (PartitionManager.Mount_Current_Storage(true)) {
if (arg == "internal") {
// Save the current zip location to the external variable
DataManager::SetValue(TW_ZIP_EXTERNAL_VAR, DataManager::GetStrValue(TW_ZIP_LOCATION_VAR));
diff --git a/partition.cpp b/partition.cpp
index 29a20dc9f..017af8829 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -27,6 +27,7 @@
#include <sys/vfs.h>
#include <sys/mount.h>
#include <unistd.h>
+#include <dirent.h>
#include "variables.h"
#include "common.h"
@@ -35,8 +36,6 @@
extern "C" {
#include "extra-functions.h"
int __system(const char *command);
- FILE * __popen(const char *program, const char *type);
- int __pclose(FILE *iop);
}
TWPartition::TWPartition(void) {
@@ -81,13 +80,13 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
char full_line[MAX_FSTAB_LINE_LENGTH], item[MAX_FSTAB_LINE_LENGTH];
int line_len = Line.size(), index = 0, item_index = 0;
char* ptr;
+ string Flags;
strncpy(full_line, Line.c_str(), line_len);
- while (index < line_len) {
+ for (index = 0; index < line_len; index++) {
if (full_line[index] <= 32)
full_line[index] = '\0';
- index++;
}
string mount_pt(full_line);
Mount_Point = mount_pt;
@@ -124,6 +123,10 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
// Partition length
ptr += 7;
Length = atoi(ptr);
+ } else if (strlen(ptr) > 6 && strncmp(ptr, "flags=", 6) == 0) {
+ // Custom flags, save for later so that new values aren't overwritten by defaults
+ ptr += 6;
+ Flags = ptr;
} else {
// Unhandled data
LOGI("Unhandled fstab information: '%s', %i\n", ptr, index);
@@ -144,14 +147,16 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
if (Mount_Point == "/system") {
Display_Name = "System";
Wipe_Available_in_GUI = true;
- Update_Size(Display_Error);
- int backup_display_size = (int)(Backup_Size / 1048576LLU);
- DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
} else if (Mount_Point == "/data") {
Display_Name = "Data";
Wipe_Available_in_GUI = true;
+ Wipe_During_Factory_Reset = true;
#ifdef RECOVERY_SDCARD_ON_DATA
Has_Data_Media = true;
+ Is_Storage = true;
+ Storage_Path = "/data/media";
+ Make_Dir("/sdcard", Display_Error);
+ Make_Dir("/emmc", Display_Error);
#endif
#ifdef TW_INCLUDE_CRYPTO
Can_Be_Encrypted = true;
@@ -161,36 +166,23 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
DataManager::SetValue(TW_IS_ENCRYPTED, 1);
DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
DataManager::SetValue("tw_crypto_display", "");
- } else
- Update_Size(Display_Error);
-#else
- Update_Size(Display_Error);
+ }
#endif
- int backup_display_size = (int)(Backup_Size / 1048576LLU);
- DataManager::SetValue(TW_BACKUP_DATA_SIZE, backup_display_size);
} else if (Mount_Point == "/cache") {
Display_Name = "Cache";
Wipe_Available_in_GUI = true;
+ Wipe_During_Factory_Reset = true;
Update_Size(Display_Error);
- int backup_display_size = (int)(Backup_Size / 1048576LLU);
- DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
} else if (Mount_Point == "/datadata") {
+ Wipe_During_Factory_Reset = true;
Display_Name = "DataData";
Is_SubPartition = true;
SubPartition_Of = "/data";
- Update_Size(Display_Error);
DataManager::SetValue(TW_HAS_DATADATA, 1);
} else if (Mount_Point == "/sd-ext") {
+ Wipe_During_Factory_Reset = true;
Display_Name = "SD-Ext";
Wipe_Available_in_GUI = true;
- Update_Size(Display_Error);
- int backup_display_size = (int)(Backup_Size / 1048576LLU);
- DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
- if (Backup_Size == 0) {
- DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
- DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
- } else
- DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
} else
Update_Size(Display_Error);
} else if (Is_Image(Fstab_File_System)) {
@@ -214,7 +206,62 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
}
}
- return 1;
+ // Process any custom flags
+ if (Flags.size() > 0)
+ Process_Flags(Flags, Display_Error);
+
+ return true;
+}
+
+bool TWPartition::Process_Flags(string Flags, bool Display_Error) {
+ char flags[MAX_FSTAB_LINE_LENGTH];
+ int flags_len, index = 0;
+ char* ptr;
+
+ strcpy(flags, Flags.c_str());
+ flags_len = Flags.size();
+ for (index = 0; index < flags_len; index++) {
+ if (flags[index] == ';')
+ flags[index] = '\0';
+ }
+
+ index = 0;
+ while (index < flags_len) {
+ while (index < flags_len && flags[index] == '\0')
+ index++;
+ if (index >= flags_len)
+ continue;
+ ptr = flags + index;
+ if (strcmp(ptr, "removable") == 0) {
+ Removable = true;
+ } else if (strcmp(ptr, "storage") == 0) {
+ Is_Storage = true;
+ } else if (strlen(ptr) > 15 && strncmp(ptr, "subpartitionof=", 15) == 0) {
+ ptr += 13;
+ Is_SubPartition = true;
+ SubPartition_Of = ptr;
+ } else if (strlen(ptr) > 8 && strncmp(ptr, "symlink=", 8) == 0) {
+ ptr += 8;
+ Symlink_Path = ptr;
+ } else if (strlen(ptr) > 8 && strncmp(ptr, "display=", 8) == 0) {
+ ptr += 8;
+ Display_Name = ptr;
+ } else if (strlen(ptr) > 10 && strncmp(ptr, "blocksize=", 10) == 0) {
+ ptr += 10;
+ Format_Block_Size = atoi(ptr);
+ } else if (strlen(ptr) > 7 && strncmp(ptr, "length=", 7) == 0) {
+ ptr += 7;
+ Length = atoi(ptr);
+ } else {
+ if (Display_Error)
+ LOGE("Unhandled flag: '%s'\n", ptr);
+ else
+ LOGI("Unhandled flag: '%s'\n", ptr);
+ }
+ while (index < flags_len && flags[index] != '\0')
+ index++;
+ }
+ return true;
}
bool TWPartition::Is_File_System(string File_System) {
@@ -238,6 +285,22 @@ bool TWPartition::Is_Image(string File_System) {
return false;
}
+bool TWPartition::Make_Dir(string Path, bool Display_Error) {
+ if (!Path_Exists(Path)) {
+ if (mkdir(Path.c_str(), 0777) == -1) {
+ if (Display_Error)
+ LOGE("Can not create '%s' folder.\n", Path.c_str());
+ else
+ LOGI("Can not create '%s' folder.\n", Path.c_str());
+ return false;
+ } else {
+ LOGI("Created '%s' folder.\n", Path.c_str());
+ return true;
+ }
+ }
+ return true;
+}
+
void TWPartition::Setup_File_System(bool Display_Error) {
struct statfs st;
@@ -252,15 +315,7 @@ void TWPartition::Setup_File_System(bool Display_Error) {
Is_Present = true;
}
// Make the mount point folder if it doesn't exist
- if (!Path_Exists(Mount_Point.c_str())) {
- if (mkdir(Mount_Point.c_str(), 0777) == -1) {
- if (Display_Error)
- LOGE("Can not create '%s' folder.\n", Mount_Point.c_str());
- else
- LOGI("Can not create '%s' folder.\n", Mount_Point.c_str());
- } else
- LOGI("Created '%s' folder.\n", Mount_Point.c_str());
- }
+ Make_Dir(Mount_Point, Display_Error);
Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1);
Backup_Name = Display_Name;
Backup_Method = FILES;
@@ -315,7 +370,30 @@ void TWPartition::Find_Real_Block_Device(string& Block, bool Display_Error) {
}
}
-bool TWPartition::Get_Size_Via_df(string Path, bool Display_Error) {
+bool TWPartition::Get_Size_Via_statfs(bool Display_Error) {
+ struct statfs st;
+ string Local_Path = Mount_Point + "/.";
+
+ if (!Mount(Display_Error))
+ return false;
+
+ if (statfs(Local_Path.c_str(), &st) != 0) {
+ if (!Removable) {
+ if (Display_Error)
+ LOGE("Unable to statfs '%s'\n", Local_Path.c_str());
+ else
+ LOGI("Unable to statfs '%s'\n", Local_Path.c_str());
+ }
+ return false;
+ }
+ Size = (st.f_blocks * st.f_bsize);
+ Used = ((st.f_blocks - st.f_bfree) * st.f_bsize);
+ Free = (st.f_bfree * st.f_bsize);
+ Backup_Size = Used;
+ return true;
+}
+
+bool TWPartition::Get_Size_Via_df(bool Display_Error) {
FILE* fp;
char command[255], line[512];
int include_block = 1;
@@ -325,10 +403,13 @@ bool TWPartition::Get_Size_Via_df(string Path, bool Display_Error) {
return false;
min_len = Block_Device.size() + 2;
- sprintf(command, "df %s", Path.c_str());
- fp = __popen(command, "r");
- if (fp == NULL)
+ sprintf(command, "df %s > /tmp/dfoutput.txt", Mount_Point.c_str());
+ __system(command);
+ fp = fopen("/tmp/dfoutput.txt", "rt");
+ if (fp == NULL) {
+ LOGI("Unable to open /tmp/dfoutput.txt.\n");
return false;
+ }
while (fgets(line, sizeof(line), fp) != NULL)
{
@@ -362,19 +443,42 @@ bool TWPartition::Get_Size_Via_df(string Path, bool Display_Error) {
return true;
}
-unsigned long long TWPartition::Get_Size_Via_du(string Path, bool Display_Error) {
- char cmd[512];
- sprintf(cmd, "du -sk %s | awk '{ print $1 }'", Path.c_str());
+unsigned long long TWPartition::Get_Folder_Size(string Path, bool Display_Error) {
+ DIR* d;
+ struct dirent* de;
+ struct stat st;
+ char path2[1024], filename[1024];
+ unsigned long long dusize = 0;
- FILE *fp;
- fp = __popen(cmd, "r");
-
- char str[512];
- fgets(str, sizeof(str), fp);
- __pclose(fp);
+ // Make a copy of path in case the data in the pointer gets overwritten later
+ strcpy(path2, Path.c_str());
- unsigned long long dusize = atol(str);
- dusize *= 1024ULL;
+ d = opendir(path2);
+ if (d == NULL)
+ {
+ LOGE("error opening '%s'\n", path2);
+ return 0;
+ }
+
+ while ((de = readdir(d)) != NULL)
+ {
+ if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
+ {
+ strcpy(filename, path2);
+ strcat(filename, "/");
+ strcat(filename, de->d_name);
+ dusize += Get_Folder_Size(filename, Display_Error);
+ }
+ else if (de->d_type == DT_REG)
+ {
+ strcpy(filename, path2);
+ strcat(filename, "/");
+ strcat(filename, de->d_name);
+ stat(filename, &st);
+ dusize += (unsigned long long)(st.st_size);
+ }
+ }
+ closedir(d);
return dusize;
}
@@ -456,6 +560,8 @@ bool TWPartition::Mount(bool Display_Error) {
} else if (!Can_Be_Mounted) {
return false;
}
+ if (Removable)
+ Check_FS_Type();
if (Is_Decrypted) {
if (mount(Decrypted_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
Check_FS_Type();
@@ -465,10 +571,16 @@ bool TWPartition::Mount(bool Display_Error) {
else
LOGI("Unable to mount decrypted block device '%s' to '%s'\n", Decrypted_Block_Device.c_str(), Mount_Point.c_str());
return false;
- } else
+ } else {
+ if (Removable)
+ Update_Size(Display_Error);
return true;
- } else
+ }
+ } else {
+ if (Removable)
+ Update_Size(Display_Error);
return true;
+ }
}
if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
Check_FS_Type();
@@ -482,13 +594,21 @@ bool TWPartition::Mount(bool Display_Error) {
else
LOGI("Unable to mount '%s'\n", Mount_Point.c_str());
return false;
- } else
+ } else {
+ if (Removable)
+ Update_Size(Display_Error);
return true;
+ }
} else
return false;
- } else
+ } else {
+ if (Removable)
+ Update_Size(Display_Error);
return true;
+ }
}
+ if (Removable)
+ Update_Size(Display_Error);
return true;
}
@@ -555,10 +675,12 @@ void TWPartition::Check_FS_Type() {
return; // Running blkid on some mtd devices causes a massive crash
if (Is_Decrypted)
- blkCommand = "blkid " + Decrypted_Block_Device;
+ blkCommand = "blkid " + Decrypted_Block_Device + " > /tmp/blkidoutput.txt";
else
- blkCommand = "blkid " + Block_Device;
- fp = __popen(blkCommand.c_str(), "r");
+ blkCommand = "blkid " + Block_Device + " > /tmp/blkidoutput.txt";
+
+ __system(blkCommand.c_str());
+ fp = fopen("/tmp/blkidoutput.txt", "rt");
while (fgets(blkOutput, sizeof(blkOutput), fp) != NULL)
{
blk = blkOutput;
@@ -672,20 +794,33 @@ bool TWPartition::Restore_Flash_Image(string restore_folder) {
}
bool TWPartition::Update_Size(bool Display_Error) {
+ bool ret = false;
+
if (!Can_Be_Mounted)
return false;
- if (!Get_Size_Via_df(Mount_Point, Display_Error))
+ if (!Mount(Display_Error))
return false;
+
+ ret = Get_Size_Via_statfs(Display_Error);
+ if (!ret || Size == 0)
+ if (!Get_Size_Via_df(Display_Error))
+ return false;
+
if (Has_Data_Media) {
if (Mount(Display_Error)) {
- unsigned long long data_used, data_media_used, actual_data;
- data_used = Get_Size_Via_du("/data/", Display_Error);
- data_media_used = Get_Size_Via_du("/data/media/", Display_Error);
- actual_data = data_used - data_media_used;
+ unsigned long long data_media_used, actual_data;
+ data_media_used = 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);
+ int fre = (int)(Free / 1048576LLU);
+ int datmed = (int)(data_media_used / 1048576LLU);
+ LOGI("Data backup size is %iMB, size: %iMB, used: %iMB, free: %iMB, in data/media: %iMB.\n", bak, total, us, fre, datmed);
} else
return false;
}
return true;
-} \ No newline at end of file
+}
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 2e50641db..b30e3b729 100644
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -71,6 +71,7 @@ int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error)
else
LOGI("Error creating fstab\n");
}
+ Update_System_Details();
return true;
}
@@ -85,12 +86,20 @@ int TWPartitionManager::Write_Fstab(void) {
return false;
}
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
- if ((*iter)->Can_Be_Mounted && (*iter)->Is_Present) {
+ if ((*iter)->Can_Be_Mounted) {
if ((*iter)->Is_Decrypted)
Line = (*iter)->Decrypted_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
else
Line = (*iter)->Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
fputs(Line.c_str(), fp);
+ // Handle subpartition tracking
+ if ((*iter)->Is_SubPartition) {
+ TWPartition* ParentPartition = Find_Partition_By_Path((*iter)->SubPartition_Of);
+ if (ParentPartition)
+ ParentPartition->Has_SubPartition = true;
+ else
+ LOGE("Unable to locate parent partition '%s' of '%s'\n", (*iter)->SubPartition_Of.c_str(), (*iter)->Mount_Point.c_str());
+ }
}
}
fclose(fp);
@@ -101,99 +110,180 @@ int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
std::vector<TWPartition*>::iterator iter;
int ret = false;
bool found = false;
- string Local_Path = Path;
-
- // Make sure that we have a leading slash
- if (Local_Path.substr(0, 1) != "/")
- Local_Path = "/" + Local_Path;
-
- // Trim the path to get the root path only
- size_t position = Local_Path.find("/", 2);
- if (position != string::npos) {
- Local_Path.resize(position);
- }
+ string Local_Path = Get_Root_Path(Path);
// Iterate through all partitions
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Mount_Point == Local_Path) {
ret = (*iter)->Mount(Display_Error);
found = true;
- } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path)
+ } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
(*iter)->Mount(Display_Error);
+ }
}
if (found) {
return ret;
} else if (Display_Error) {
- LOGE("Unable to find partition for path '%s'\n", Local_Path.c_str());
+ LOGE("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
} else {
- LOGI("Unable to find partition for path '%s'\n", Local_Path.c_str());
+ LOGI("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
}
return false;
}
int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
- std::vector<TWPartition*>::iterator iter;
+ TWPartition* Part = Find_Partition_By_Block(Block);
- for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
- if ((*iter)->Block_Device == Block)
- return (*iter)->Mount(Display_Error);
- else if ((*iter)->Alternate_Block_Device == Block)
- return (*iter)->Mount(Display_Error);
+ if (Part) {
+ if (Part->Has_SubPartition) {
+ std::vector<TWPartition*>::iterator subpart;
+
+ for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
+ if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
+ (*subpart)->Mount(Display_Error);
+ }
+ return Part->Mount(Display_Error);
+ } else
+ return Part->Mount(Display_Error);
}
if (Display_Error)
- LOGE("Unable to find partition for block '%s'\n", Block.c_str());
+ LOGE("Mount: Unable to find partition for block '%s'\n", Block.c_str());
else
- LOGI("Unable to find partition for block '%s'\n", Block.c_str());
+ LOGI("Mount: Unable to find partition for block '%s'\n", Block.c_str());
return false;
}
int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
- std::vector<TWPartition*>::iterator iter;
+ TWPartition* Part = Find_Partition_By_Name(Name);
- for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
- if ((*iter)->Display_Name == Name)
- return (*iter)->Mount(Display_Error);
+ if (Part) {
+ if (Part->Has_SubPartition) {
+ std::vector<TWPartition*>::iterator subpart;
+
+ for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
+ if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
+ (*subpart)->Mount(Display_Error);
+ }
+ return Part->Mount(Display_Error);
+ } else
+ return Part->Mount(Display_Error);
}
if (Display_Error)
- LOGE("Unable to find partition for name '%s'\n", Name.c_str());
+ LOGE("Mount: Unable to find partition for name '%s'\n", Name.c_str());
else
- LOGI("Unable to find partition for name '%s'\n", Name.c_str());
+ LOGI("Mount: Unable to find partition for name '%s'\n", Name.c_str());
return false;
- return 1;
}
int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
- LOGI("STUB TWPartitionManager::UnMount_By_Path, Path: '%s', Display_Error: %i\n", Path.c_str(), Display_Error);
- return 1;
+ std::vector<TWPartition*>::iterator iter;
+ int ret = false;
+ bool found = false;
+ string Local_Path = Get_Root_Path(Path);
+
+ // Iterate through all partitions
+ for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
+ if ((*iter)->Mount_Point == Local_Path) {
+ ret = (*iter)->UnMount(Display_Error);
+ found = true;
+ } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
+ (*iter)->UnMount(Display_Error);
+ }
+ }
+ if (found) {
+ return ret;
+ } else if (Display_Error) {
+ LOGE("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
+ } else {
+ LOGI("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
+ }
+ return false;
}
int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
- LOGI("STUB TWPartitionManager::UnMount_By_Block, Block: '%s', Display_Error: %i\n", Block.c_str(), Display_Error);
- return 1;
+ TWPartition* Part = Find_Partition_By_Block(Block);
+
+ if (Part) {
+ if (Part->Has_SubPartition) {
+ std::vector<TWPartition*>::iterator subpart;
+
+ for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
+ if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
+ (*subpart)->UnMount(Display_Error);
+ }
+ return Part->UnMount(Display_Error);
+ } else
+ return Part->UnMount(Display_Error);
+ }
+ if (Display_Error)
+ LOGE("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
+ else
+ LOGI("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
+ return false;
}
int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
- LOGI("STUB TWPartitionManager::UnMount_By_Name, Name: '%s', Display_Error: %i\n", Name.c_str(), Display_Error);
- return 1;
+ TWPartition* Part = Find_Partition_By_Name(Name);
+
+ if (Part) {
+ if (Part->Has_SubPartition) {
+ std::vector<TWPartition*>::iterator subpart;
+
+ for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
+ if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
+ (*subpart)->UnMount(Display_Error);
+ }
+ return Part->UnMount(Display_Error);
+ } else
+ return Part->UnMount(Display_Error);
+ }
+ if (Display_Error)
+ LOGE("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
+ else
+ LOGI("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
+ return false;
}
int TWPartitionManager::Is_Mounted_By_Path(string Path) {
- LOGI("STUB TWPartitionManager::Is_Mounted_By_Path, Path: '%s'\n", Path.c_str());
- return 1;
+ TWPartition* Part = Find_Partition_By_Path(Path);
+
+ if (Part)
+ return Part->Is_Mounted();
+ else
+ LOGI("Is_Mounted: Unable to find partition for path '%s'\n", Path.c_str());
+ return false;
}
int TWPartitionManager::Is_Mounted_By_Block(string Block) {
- LOGI("STUB TWPartitionManager::Is_Mounted_By_Block, Block: '%s'\n", Block.c_str());
- return 1;
+ TWPartition* Part = Find_Partition_By_Block(Block);
+
+ if (Part)
+ return Part->Is_Mounted();
+ else
+ LOGI("Is_Mounted: Unable to find partition for block '%s'\n", Block.c_str());
+ return false;
}
int TWPartitionManager::Is_Mounted_By_Name(string Name) {
- LOGI("STUB TWPartitionManager::Is_Mounted_By_Name, Name: '%s'\n", Name.c_str());
- return 1;
+ TWPartition* Part = Find_Partition_By_Name(Name);
+
+ if (Part)
+ return Part->Is_Mounted();
+ else
+ LOGI("Is_Mounted: Unable to find partition for name '%s'\n", Name.c_str());
+ return false;
}
int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
- return Mount_By_Path(DataManager::GetCurrentStoragePath(), Display_Error);
+ string current_storage_path = DataManager::GetCurrentStoragePath();
+
+ if (Mount_By_Path(current_storage_path, Display_Error)) {
+ TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
+ if (FreeStorage)
+ DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
+ return true;
+ }
+ return false;
}
int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
@@ -202,21 +292,32 @@ int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
std::vector<TWPartition*>::iterator iter;
+ string Local_Path = Get_Root_Path(Path);
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
- if ((*iter)->Mount_Point == Path)
+ if ((*iter)->Mount_Point == Local_Path)
return (*iter);
}
return NULL;
}
TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
- LOGI("STUB TWPartitionManager::Find_Partition_By_Block, Block: '%s'\n", Block.c_str());
+ std::vector<TWPartition*>::iterator iter;
+
+ for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
+ if ((*iter)->Block_Device == Block || (*iter)->Alternate_Block_Device == Block || ((*iter)->Is_Decrypted && (*iter)->Decrypted_Block_Device == Block))
+ return (*iter);
+ }
return NULL;
}
TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
- LOGI("STUB TWPartitionManager::Find_Partition_By_Name, Name: '%s'\n", Name.c_str());
+ std::vector<TWPartition*>::iterator iter;
+
+ for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
+ if ((*iter)->Display_Name == Name)
+ return (*iter);
+ }
return NULL;
}
@@ -256,18 +357,44 @@ int TWPartitionManager::Factory_Reset(void) {
}
void TWPartitionManager::Refresh_Sizes(void) {
- LOGI("STUB TWPartitionManager::Refresh_Sizes\n");
+ Update_System_Details();
return;
}
void TWPartitionManager::Update_System_Details(void) {
std::vector<TWPartition*>::iterator iter;
+ int data_size = 0;
LOGI("Updating system details...\n");
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
- (*iter)->Check_FS_Type();
- (*iter)->Update_Size(false);
+ if ((*iter)->Can_Be_Mounted) {
+ (*iter)->Update_Size(true);
+ if ((*iter)->Mount_Point == "/system") {
+ int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
+ DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
+ } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
+ data_size += (int)((*iter)->Backup_Size / 1048576LLU);
+ } else if ((*iter)->Mount_Point == "/cache") {
+ int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
+ DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
+ } else if ((*iter)->Mount_Point == "/sd-ext") {
+ int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
+ DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
+ if ((*iter)->Backup_Size == 0) {
+ DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
+ DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
+ } else
+ DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
+ }
+ }
}
+ DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
+ string current_storage_path = DataManager::GetCurrentStoragePath();
+ TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
+ if (FreeStorage)
+ DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
+ else
+ LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
if (!Write_Fstab())
LOGE("Error creating fstab\n");
return;
@@ -318,4 +445,19 @@ int TWPartitionManager::Decrypt_Device(string Password) {
return -1;
#endif
return 1;
-} \ No newline at end of file
+}
+
+string TWPartitionManager::Get_Root_Path(string Path) {
+ string Local_Path = Path;
+
+ // Make sure that we have a leading slash
+ if (Local_Path.substr(0, 1) != "/")
+ Local_Path = "/" + Local_Path;
+
+ // Trim the path to get the root path only
+ size_t position = Local_Path.find("/", 2);
+ if (position != string::npos) {
+ Local_Path.resize(position);
+ }
+ return Local_Path;
+}
diff --git a/partitions.hpp b/partitions.hpp
index 13ce02876..5ed723c95 100644
--- a/partitions.hpp
+++ b/partitions.hpp
@@ -52,7 +52,7 @@ public:
virtual bool Wipe(); // Wipes the partition
virtual bool Backup(string backup_folder); // Backs up the partition to the folder specified
virtual bool Restore(string restore_folder); // Restores the partition using the backup folder provided
- static string Backup_Method_By_Name(); // Returns a string of the backup method for human readable output
+ virtual string Backup_Method_By_Name(); // Returns a string of the backup method for human readable output
virtual bool Decrypt(string Password); // Decrypts the partition, return 0 for failure and -1 for success
virtual bool Wipe_Encryption(); // Ignores wipe commands for /data/media devices and formats the original block device
virtual void Check_FS_Type(); // Checks the fs type using blkid, does not do anything on MTD / yaffs2 because this crashes on some devices
@@ -67,6 +67,7 @@ protected:
bool Wipe_During_Factory_Reset; // Indicates that this partition is wiped during a factory reset
bool Wipe_Available_in_GUI; // Inidcates that the wipe can be user initiated in the GUI system
bool Is_SubPartition; // Indicates that this partition is a sub-partition of another partition (e.g. datadata is a sub-partition of data)
+ bool Has_SubPartition; // Indicates that this partition has a sub-partition
string SubPartition_Of; // Indicates which partition is the parent partition of this partition (e.g. /data is the parent partition of /datadata)
string Symlink_Path; // Symlink path (e.g. /data/media)
string Symlink_Mount_Point; // /sdcard could be the symlink mount point for /data/media
@@ -95,6 +96,7 @@ protected:
int Format_Block_Size; // Block size for formatting
private:
+ bool Process_Flags(string Flags, bool Display_Error); // Process custom fstab flags
bool Is_File_System(string File_System); // Checks to see if the file system given is considered a file system
bool Is_Image(string File_System); // Checks to see if the file system given is considered an image
void Setup_File_System(bool Display_Error); // Sets defaults for a file system partition
@@ -102,7 +104,6 @@ private:
bool Path_Exists(string Path); // Checks to see if the Path exists in the file system
void Find_Real_Block_Device(string& Block_Device, bool Display_Error); // Checks the block device given and follows symlinks until it gets to the real block device
bool Find_Partition_Size(); // Finds the partition size from /proc/partitions
- bool Get_Size_Via_df(string Path, bool Display_Error); // Uses df to get sizes
unsigned long long Get_Size_Via_du(string Path, bool Display_Error); // Uses du to get sizes
void Flip_Block_Device(); // Flips the Block_Device and Alternate_Block_Device
bool Wipe_EXT23(); // Formats as ext3 or ext2
@@ -117,6 +118,10 @@ private:
bool Restore_Tar(string restore_folder); // Restore using tar for file systems
bool Restore_DD(string restore_folder); // Restore using dd for emmc memory types
bool Restore_Flash_Image(string restore_folder); // Restore using flash_image for MTD memory types
+ bool Get_Size_Via_statfs(bool Display_Error); // Get Partition size, used, and free space using statfs
+ bool Get_Size_Via_df(bool Display_Error); // Get Partition size, used, and free space using df command
+ unsigned long long Get_Folder_Size(string Path, bool Display_Error); // Gets the size of the files in a folder and all of its subfolders
+ bool Make_Dir(string Path, bool Display_Error); // Creates a directory if it doesn't already exist
friend class TWPartitionManager;
};
@@ -154,9 +159,10 @@ public:
virtual void Refresh_Sizes(); // Refreshes size data of partitions
virtual void Update_System_Details(); // Updates fstab, file systems, sizes, etc.
virtual int Decrypt_Device(string Password); // Attempt to decrypt any encrypted partitions
+ virtual string Get_Root_Path(string Path); // Trims any trailing folders or filenames from the path, also adds a leading / if not present
private:
- std::vector<TWPartition*> Partitions;
+ std::vector<TWPartition*> Partitions; // Vector list of all partitions
};
extern TWPartitionManager PartitionManager;
diff --git a/recovery.cpp b/recovery.cpp
index 319cdc72a..450f36330 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -51,6 +51,7 @@ extern "C" {
#include "gui/gui.h"
}
#include "partitions.hpp"
+#include "variables.h"
TWPartitionManager PartitionManager;
char device_id[64];
@@ -787,7 +788,7 @@ main(int argc, char **argv) {
return 0;
}
- printf("Starting TWRP %s on %s", EXPAND(TW_VERSION_STR), ctime(&start));
+ printf("Starting TWRP %s on %s", TW_VERSION_STR, ctime(&start));
// Recovery needs to install world-readable files, so clear umask
// set by init
umask(0);
@@ -802,7 +803,7 @@ main(int argc, char **argv) {
// Load default values to set DataManager constants and handle ifdefs
DataManager_LoadDefaults();
printf("Starting the UI...");
- printf(" result was: %i\n", gui_init());
+ gui_init();
printf("=> Installing busybox into /sbin\n");
__system("/sbin/bbinstall.sh"); // Let's install busybox
printf("=> Linking mtab\n");
diff --git a/roots.cpp b/roots.cpp
index 3bd680157..e74747378 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -40,7 +40,8 @@ static int parse_options(char* options, Volume* volume) {
while ((option = strtok(options, ","))) {
options = NULL;
- if (strncmp(option, "length=", 7) == 0) {
+ if (strncmp(option, "flags=", 6) == 0) continue;
+ if (strncmp(option, "length=", 7) == 0) {
volume->length = strtoll(option+7, NULL, 10);
} else {
LOGE("bad option \"%s\"\n", option);