Improve storage size code, mount, unmount
Add flag parsing from recovery.fstab
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -10,7 +10,6 @@ on init
|
||||
|
||||
symlink /system/etc /etc
|
||||
|
||||
mkdir /emmc
|
||||
mkdir /system
|
||||
mkdir /data
|
||||
mkdir /cache
|
||||
|
||||
+7
-15
@@ -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));
|
||||
|
||||
+197
-62
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+192
-50
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
+9
-3
@@ -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;
|
||||
|
||||
+3
-2
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user