From 43d8b0077072ff4ef5ffa07be5dcbf7a73fe499f Mon Sep 17 00:00:00 2001 From: Dees_Troy Date: Mon, 17 Sep 2012 16:00:01 -0400 Subject: Update backup and restore code, adb sideload Fixed a problem with using make_ext4fs by making its lib a dynamic lib. Added ADB sideload zip install feature - no way to cancel it yet. Improve backup and restore code. --- partition.cpp | 266 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 178 insertions(+), 88 deletions(-) (limited to 'partition.cpp') diff --git a/partition.cpp b/partition.cpp index f4fa0d86e..521722774 100644 --- a/partition.cpp +++ b/partition.cpp @@ -37,11 +37,11 @@ #include "common.h" #include "partitions.hpp" #include "data.hpp" +#include "twrp-functions.hpp" extern "C" { #include "mtdutils/mtdutils.h" #include "mtdutils/mounts.h" - #include "extra-functions.h" - int __system(const char *command); + #include "makelist.h" } TWPartition::TWPartition(void) { @@ -333,7 +333,7 @@ bool TWPartition::Is_Image(string File_System) { } bool TWPartition::Make_Dir(string Path, bool Display_Error) { - if (!Path_Exists(Path)) { + if (!TWFunc::Path_Exists(Path)) { if (mkdir(Path.c_str(), 0777) == -1) { if (Display_Error) LOGE("Can not create '%s' folder.\n", Path.c_str()); @@ -479,7 +479,7 @@ bool TWPartition::Get_Size_Via_df(bool Display_Error) { min_len = Actual_Block_Device.size() + 2; sprintf(command, "df %s > /tmp/dfoutput.txt", Mount_Point.c_str()); - __system(command); + system(command); fp = fopen("/tmp/dfoutput.txt", "rt"); if (fp == NULL) { LOGI("Unable to open /tmp/dfoutput.txt.\n"); @@ -518,46 +518,6 @@ bool TWPartition::Get_Size_Via_df(bool Display_Error) { return true; } -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; - - // Make a copy of path in case the data in the pointer gets overwritten later - strcpy(path2, Path.c_str()); - - 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; -} - bool TWPartition::Find_Partition_Size(void) { FILE* fp; char line[512]; @@ -590,16 +550,6 @@ bool TWPartition::Find_Partition_Size(void) { return false; } -bool TWPartition::Path_Exists(string Path) { - // Check to see if the Path exists - struct statfs st; - - if (statfs(Path.c_str(), &st) != 0) - return false; - else - return true; -} - void TWPartition::Flip_Block_Device(void) { string temp; @@ -655,7 +605,7 @@ bool TWPartition::Mount(bool Display_Error) { string Command; Command = "mount " + Symlink_Path + " " + Symlink_Mount_Point; - __system(Command.c_str()); + system(Command.c_str()); } return true; } @@ -727,7 +677,38 @@ bool TWPartition::Backup(string backup_folder) { return false; } +bool TWPartition::Check_MD5(string restore_folder) { + string Full_Filename; + char split_filename[512]; + int index = 0; + + Full_Filename = restore_folder + "/" + Backup_FileName; + LOGI("Full_Filename: '%s'\n", Full_Filename.c_str()); + if (!TWFunc::Path_Exists(Full_Filename)) { + // This is a split archive, we presume + sprintf(split_filename, "%s%03i", Full_Filename.c_str(), index); + while (index < 1000 && TWFunc::Path_Exists(split_filename)) { + if (TWFunc::Check_MD5(split_filename) == 0) { + LOGE("MD5 failed to match on '%s'.\n", split_filename); + return false; + } + index++; + sprintf(split_filename, "%s%03i", Full_Filename.c_str(), index); + LOGI("Full_Filename: '%s'\n", Full_Filename.c_str()); + } + } else { + // Single file archive + if (TWFunc::Check_MD5(Full_Filename) == 0) { + LOGE("MD5 failed to match on '%s'.\n", split_filename); + return false; + } else + return true; + } + return false; +} + bool TWPartition::Restore(string restore_folder) { + ui_print("Restoring %s...\n", Display_Name.c_str()); if (Backup_Method == FILES) return Restore_Tar(restore_folder); else if (Backup_Method == DD) @@ -797,7 +778,7 @@ void TWPartition::Check_FS_Type() { Find_Actual_Block_Device(); blkCommand = "blkid " + Actual_Block_Device + " > /tmp/blkidoutput.txt"; - __system(blkCommand.c_str()); + system(blkCommand.c_str()); fp = fopen("/tmp/blkidoutput.txt", "rt"); while (fgets(blkOutput, sizeof(blkOutput), fp) != NULL) { @@ -847,7 +828,7 @@ void TWPartition::Check_FS_Type() { Current_File_System = arg; } } - __pclose(fp); + fclose(fp); return; } @@ -855,14 +836,14 @@ bool TWPartition::Wipe_EXT23() { if (!UnMount(true)) return false; - if (Path_Exists("/sbin/mke2fs")) { + if (TWFunc::Path_Exists("/sbin/mke2fs")) { char command[512]; ui_print("Formatting %s using mke2fs...\n", Display_Name.c_str()); Find_Actual_Block_Device(); sprintf(command, "mke2fs -t %s -m 0 %s", Current_File_System.c_str(), Actual_Block_Device.c_str()); LOGI("mke2fs command: %s\n", command); - if (__system(command) == 0) { + if (system(command) == 0) { ui_print("Done.\n"); return true; } else { @@ -879,7 +860,7 @@ bool TWPartition::Wipe_EXT4() { if (!UnMount(true)) return false; - if (Path_Exists("/sbin/make_ext4fs")) { + if (TWFunc::Path_Exists("/sbin/make_ext4fs")) { string Command; ui_print("Formatting %s using make_ext4fs...\n", Display_Name.c_str()); @@ -894,7 +875,7 @@ bool TWPartition::Wipe_EXT4() { } Command += " " + Actual_Block_Device; LOGI("make_ext4fs command: %s\n", Command.c_str()); - if (__system(Command.c_str()) == 0) { + if (system(Command.c_str()) == 0) { ui_print("Done.\n"); return true; } else { @@ -913,14 +894,14 @@ bool TWPartition::Wipe_FAT() { if (Backup_Name == "and-sec") // Don't format if it's android secure return Wipe_RMRF(); - if (Path_Exists("/sbin/mkdosfs")) { + if (TWFunc::Path_Exists("/sbin/mkdosfs")) { if (!UnMount(true)) return false; ui_print("Formatting %s using mkdosfs...\n", Display_Name.c_str()); Find_Actual_Block_Device(); sprintf(command,"mkdosfs %s", Actual_Block_Device.c_str()); // use mkdosfs to format it - if (__system(command) == 0) { + if (system(command) == 0) { ui_print("Done.\n"); return true; } else { @@ -981,7 +962,7 @@ bool TWPartition::Wipe_RMRF() { } LOGI("rm -rf command is: '%s'\n", cmd); - __system(cmd); + system(cmd); return true; } @@ -993,8 +974,8 @@ bool TWPartition::Wipe_Data_Without_Wiping_Media() { return false; ui_print("Wiping data without wiping /data/media ...\n"); - __system("rm -f /data/*"); - __system("rm -f /data/.*"); + system("rm -f /data/*"); + system("rm -f /data/.*"); DIR* d; d = opendir("/data"); @@ -1005,7 +986,7 @@ bool TWPartition::Wipe_Data_Without_Wiping_Media() { if (strcmp(de->d_name, "media") == 0) continue; sprintf(cmd, "rm -fr /data/%s", de->d_name); - __system(cmd); + system(cmd); } closedir(d); } @@ -1014,34 +995,142 @@ bool TWPartition::Wipe_Data_Without_Wiping_Media() { } bool TWPartition::Backup_Tar(string backup_folder) { - LOGI("STUB TWPartition::Backup_Tar, backup_folder: '%s'\n", backup_folder.c_str()); - return 1; + char back_name[255]; + string Full_FileName, Tar_Args, Command; + int use_compression; + + if (!Mount(true)) + return false; + + ui_print("Backing up %s...\n", Display_Name.c_str()); + + DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression); + if (use_compression) + Tar_Args = "-cz"; + else + Tar_Args = "-c"; + + sprintf(back_name, "%s.%s.win", Backup_Name.c_str(), Current_File_System.c_str()); + Backup_FileName = back_name; + + Full_FileName = backup_folder + "/" + Backup_FileName; + if (Backup_Size > MAX_ARCHIVE_SIZE) { + // This backup needs to be split into multiple archives + LOGE("Multiple archive splitting is not implemented yet!\n"); + return false; + } else { + if (Has_Data_Media) + Command = "cd " + Mount_Point + " && tar " + Tar_Args + " ./ --exclude='media*' -f '" + Full_FileName + "'"; + else + Command = "cd " + Mount_Point + " && tar " + Tar_Args + " -f '" + Full_FileName + "' ./*"; + LOGI("Backup command: '%s'\n", Command.c_str()); + system(Command.c_str()); + } + return true; } bool TWPartition::Backup_DD(string backup_folder) { - LOGI("STUB TWPartition::Backup_DD, backup_folder: '%s'\n", backup_folder.c_str()); - return 1; + char back_name[255]; + string Full_FileName, Command; + int use_compression; + + ui_print("Backing up %s...\n", Display_Name.c_str()); + + sprintf(back_name, "%s.%s.win", Backup_Name.c_str(), Current_File_System.c_str()); + Backup_FileName = back_name; + + Full_FileName = backup_folder + "/" + Backup_FileName; + + Command = "dd if=" + Actual_Block_Device + " of='" + Full_FileName + "'"; + LOGI("Backup command: '%s'\n", Command.c_str()); + system(Command.c_str()); + return true; } bool TWPartition::Backup_Dump_Image(string backup_folder) { - LOGI("STUB TWPartition::Backup_Dump_Image, backup_folder: '%s'\n", backup_folder.c_str()); - return 1; + char back_name[255]; + string Full_FileName, Command; + int use_compression; + + ui_print("Backing up %s...\n", Display_Name.c_str()); + + sprintf(back_name, "%s.%s.win", Backup_Name.c_str(), Current_File_System.c_str()); + Backup_FileName = back_name; + + Full_FileName = backup_folder + "/" + Backup_FileName; + + Command = "dump_image " + MTD_Name + " '" + Full_FileName + "'"; + LOGI("Backup command: '%s'\n", Command.c_str()); + system(Command.c_str()); + return true; } bool TWPartition::Restore_Tar(string restore_folder) { - LOGI("STUB TWPartition::Restore_Tar, backup_folder: '%s'\n", restore_folder.c_str()); - return 1; + size_t first_period, second_period; + string Restore_File_System, Full_FileName, Command; + + LOGI("Restore filename is: %s\n", Backup_FileName.c_str()); + + // Parse backup filename to extract the file system before wiping + first_period = Backup_FileName.find("."); + if (first_period == string::npos) { + LOGE("Unable to find file system (first period).\n"); + return false; + } + Restore_File_System = Backup_FileName.substr(first_period + 1, Backup_FileName.size() - first_period - 1); + second_period = Restore_File_System.find("."); + if (second_period == string::npos) { + LOGE("Unable to find file system (second period).\n"); + return false; + } + Restore_File_System.resize(second_period); + LOGI("Restore file system is: '%s'.\n", Restore_File_System.c_str()); + Current_File_System = Restore_File_System; + ui_print("Wiping %s...\n", Display_Name.c_str()); + if (!Wipe()) + return false; + + if (!Mount(true)) + return false; + + Full_FileName = restore_folder + "/" + Backup_FileName; + ui_print("Restoring %s...\n", Display_Name.c_str()); + if (!TWFunc::Path_Exists(Full_FileName)) { + // This backup is multiple archives + LOGE("Multiple archive not implemented yet.\n"); + return false; + } else { + Command = "cd " + Mount_Point + " && tar -xf '" + Full_FileName + "'"; + LOGI("Restore command: '%s'\n", Command.c_str()); + system(Command.c_str()); + } + return true; } bool TWPartition::Restore_DD(string restore_folder) { - LOGI("STUB TWPartition::Restore_DD, backup_folder: '%s'\n", restore_folder.c_str()); - return 1; + string Full_FileName, Command; + + ui_print("Restoring %s...\n", Display_Name.c_str()); + Full_FileName = restore_folder + "/" + Backup_FileName; + Command = "dd bs=4096 if='" + Full_FileName + "' of=" + Actual_Block_Device; + LOGI("Restore command: '%s'\n", Command.c_str()); + system(Command.c_str()); + return true; } bool TWPartition::Restore_Flash_Image(string restore_folder) { - LOGI("STUB TWPartition::Restore_Flash_Image, backup_folder: '%s'\n", restore_folder.c_str()); - // might erase image first just to ensure that it flashes - return 1; + string Full_FileName, Command; + + ui_print("Restoring %s...\n", Display_Name.c_str()); + Full_FileName = restore_folder + "/" + Backup_FileName; + // Sometimes flash image doesn't like to flash due to the first 2KB matching, so we erase first to ensure that it flashes + Command = "erase_image " + MTD_Name; + LOGI("Erase command: '%s'\n", Command.c_str()); + system(Command.c_str()); + Command = "flash_image " + MTD_Name + " '" + Full_FileName + "'"; + LOGI("Restore command: '%s'\n", Command.c_str()); + system(Command.c_str()); + return true; } bool TWPartition::Update_Size(bool Display_Error) { @@ -1064,7 +1153,8 @@ bool TWPartition::Update_Size(bool Display_Error) { if (Has_Data_Media) { if (Mount(Display_Error)) { unsigned long long data_media_used, actual_data; - data_media_used = Get_Folder_Size("/data/media", Display_Error); + Used = TWFunc::Get_Folder_Size("/data", Display_Error); + data_media_used = TWFunc::Get_Folder_Size("/data/media", Display_Error); actual_data = Used - data_media_used; Backup_Size = actual_data; int bak = (int)(Backup_Size / 1048576LLU); @@ -1082,12 +1172,12 @@ bool TWPartition::Update_Size(bool Display_Error) { void TWPartition::Find_Actual_Block_Device(void) { if (Is_Decrypted) { Actual_Block_Device = Decrypted_Block_Device; - if (Path_Exists(Primary_Block_Device)) + if (TWFunc::Path_Exists(Primary_Block_Device)) Is_Present = true; - } else if (Path_Exists(Primary_Block_Device)) { + } else if (TWFunc::Path_Exists(Primary_Block_Device)) { Is_Present = true; Actual_Block_Device = Primary_Block_Device; - } else if (!Alternate_Block_Device.empty() && Path_Exists(Alternate_Block_Device)) { + } else if (!Alternate_Block_Device.empty() && TWFunc::Path_Exists(Alternate_Block_Device)) { Flip_Block_Device(); Actual_Block_Device = Primary_Block_Device; Is_Present = true; @@ -1102,10 +1192,10 @@ void TWPartition::Recreate_Media_Folder(void) { LOGE("Unable to recreate /data/media folder.\n"); } else { LOGI("Recreating /data/media folder.\n"); - __system("cd /data && mkdir media && chmod 755 media"); + system("cd /data && mkdir media && chmod 755 media"); Command = "umount " + Symlink_Mount_Point; - __system(Command.c_str()); + system(Command.c_str()); Command = "mount " + Symlink_Path + " " + Symlink_Mount_Point; - __system(Command.c_str()); + system(Command.c_str()); } -} \ No newline at end of file +} -- cgit v1.2.3