summaryrefslogtreecommitdiffstats
path: root/partition.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'partition.cpp')
-rw-r--r--partition.cpp259
1 files changed, 197 insertions, 62 deletions
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
+}