diff options
author | Ethan Yonker <dees_troy@teamw.in> | 2014-07-03 22:09:22 +0200 |
---|---|---|
committer | Ethan Yonker <dees_troy@teamw.in> | 2014-07-09 15:52:18 +0200 |
commit | 1b7a31bd65d4e6bf5e337d6280e3d5319d460bef (patch) | |
tree | ebe7d27ea5681d1b3c772a7bc2e80025e94435a6 | |
parent | Color in the console (diff) | |
download | android_bootable_recovery-1b7a31bd65d4e6bf5e337d6280e3d5319d460bef.tar android_bootable_recovery-1b7a31bd65d4e6bf5e337d6280e3d5319d460bef.tar.gz android_bootable_recovery-1b7a31bd65d4e6bf5e337d6280e3d5319d460bef.tar.bz2 android_bootable_recovery-1b7a31bd65d4e6bf5e337d6280e3d5319d460bef.tar.lz android_bootable_recovery-1b7a31bd65d4e6bf5e337d6280e3d5319d460bef.tar.xz android_bootable_recovery-1b7a31bd65d4e6bf5e337d6280e3d5319d460bef.tar.zst android_bootable_recovery-1b7a31bd65d4e6bf5e337d6280e3d5319d460bef.zip |
Diffstat (limited to '')
29 files changed, 1005 insertions, 72 deletions
diff --git a/Android.mk b/Android.mk index 1b4cb0751..c864ff0f7 100644 --- a/Android.mk +++ b/Android.mk @@ -24,7 +24,8 @@ LOCAL_SRC_FILES := \ twrpTar.cpp \ twrpDU.cpp \ twrpDigest.cpp \ - find_file.cpp + find_file.cpp \ + infomanager.cpp LOCAL_SRC_FILES += \ data.cpp \ diff --git a/gui/devices/1024x600/res/ui.xml b/gui/devices/1024x600/res/ui.xml index d54771941..4795ce0ed 100755 --- a/gui/devices/1024x600/res/ui.xml +++ b/gui/devices/1024x600/res/ui.xml @@ -2304,6 +2304,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col_right_x%" y="%row2_text_y%" placement="1" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2679,6 +2691,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/1024x768/res/ui.xml b/gui/devices/1024x768/res/ui.xml index f404b466d..d041c50e0 100644 --- a/gui/devices/1024x768/res/ui.xml +++ b/gui/devices/1024x768/res/ui.xml @@ -2304,6 +2304,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col_right_x%" y="%row2_text_y%" placement="1" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2679,6 +2691,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/1080x1920/res/ui.xml b/gui/devices/1080x1920/res/ui.xml index 28130b7db..f95ae090f 100644 --- a/gui/devices/1080x1920/res/ui.xml +++ b/gui/devices/1080x1920/res/ui.xml @@ -2056,6 +2056,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2429,6 +2441,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/1200x1920/res/ui.xml b/gui/devices/1200x1920/res/ui.xml index d19813947..0630e10e1 100644 --- a/gui/devices/1200x1920/res/ui.xml +++ b/gui/devices/1200x1920/res/ui.xml @@ -2059,6 +2059,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2432,6 +2444,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/1280x800/res/ui.xml b/gui/devices/1280x800/res/ui.xml index 21fc3b7a8..fdd205941 100644 --- a/gui/devices/1280x800/res/ui.xml +++ b/gui/devices/1280x800/res/ui.xml @@ -2304,6 +2304,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col_right_x%" y="%row2_text_y%" placement="1" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2679,6 +2691,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/1600x2560/res/ui.xml b/gui/devices/1600x2560/res/ui.xml index b6ca28c7e..95ef1d1bf 100644 --- a/gui/devices/1600x2560/res/ui.xml +++ b/gui/devices/1600x2560/res/ui.xml @@ -2061,6 +2061,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2434,6 +2446,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -3902,7 +3920,7 @@ <resource base="slider" used="slider-used" touch="slider-touch" /> <action function="page">filemanageracction</action> </object> - + <object type="text" color="%text_color%"> <font resource="font" /> <placement x="%center_x%" y="%slider_text_y%" placement="4" /> @@ -3918,7 +3936,7 @@ <touch key="home" /> <action function="page">main</action> </object> - + <object type="template" name="footer" /> </page> diff --git a/gui/devices/1920x1200/res/ui.xml b/gui/devices/1920x1200/res/ui.xml index 5ee5b4646..2622a8878 100644 --- a/gui/devices/1920x1200/res/ui.xml +++ b/gui/devices/1920x1200/res/ui.xml @@ -2304,6 +2304,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col_right_x%" y="%row2_text_y%" placement="1" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2679,6 +2691,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/2560x1600/res/ui.xml b/gui/devices/2560x1600/res/ui.xml index 25b86194f..06880b22e 100644 --- a/gui/devices/2560x1600/res/ui.xml +++ b/gui/devices/2560x1600/res/ui.xml @@ -2304,6 +2304,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col_right_x%" y="%row2_text_y%" placement="1" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2679,6 +2691,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/320x480/res/ui.xml b/gui/devices/320x480/res/ui.xml index 369b9941e..fff85334e 100644 --- a/gui/devices/320x480/res/ui.xml +++ b/gui/devices/320x480/res/ui.xml @@ -2043,6 +2043,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2416,6 +2428,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/480x800/res/ui.xml b/gui/devices/480x800/res/ui.xml index 72b44e51f..6baa70293 100644 --- a/gui/devices/480x800/res/ui.xml +++ b/gui/devices/480x800/res/ui.xml @@ -2043,6 +2043,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2416,6 +2428,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/480x854/res/ui.xml b/gui/devices/480x854/res/ui.xml index 5026f4016..4f5a7c98a 100644 --- a/gui/devices/480x854/res/ui.xml +++ b/gui/devices/480x854/res/ui.xml @@ -2042,6 +2042,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2415,6 +2427,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/540x960/res/ui.xml b/gui/devices/540x960/res/ui.xml index bd39a18f2..11c9490a4 100644 --- a/gui/devices/540x960/res/ui.xml +++ b/gui/devices/540x960/res/ui.xml @@ -2043,6 +2043,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2416,6 +2428,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/720x1280/res/ui.xml b/gui/devices/720x1280/res/ui.xml index c9e68629a..157548564 100644 --- a/gui/devices/720x1280/res/ui.xml +++ b/gui/devices/720x1280/res/ui.xml @@ -2056,6 +2056,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2429,6 +2441,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/800x1280/res/ui.xml b/gui/devices/800x1280/res/ui.xml index b4cbb508e..abd62de8e 100755 --- a/gui/devices/800x1280/res/ui.xml +++ b/gui/devices/800x1280/res/ui.xml @@ -2044,6 +2044,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2417,6 +2429,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/gui/devices/800x480/res/ui.xml b/gui/devices/800x480/res/ui.xml index 272bf6491..6a2c08fa9 100755 --- a/gui/devices/800x480/res/ui.xml +++ b/gui/devices/800x480/res/ui.xml @@ -2312,6 +2312,18 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col_right_x%" y="%row2_text_y%" placement="1" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> @@ -2687,6 +2699,12 @@ <text>%tw_operation% %tw_partition%</text> </object> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + <object type="template" name="action_page_console" /> <object type="template" name="progress_bar" /> diff --git a/infomanager.cpp b/infomanager.cpp new file mode 100644 index 000000000..080fe1d28 --- /dev/null +++ b/infomanager.cpp @@ -0,0 +1,206 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <linux/input.h> +#include <pthread.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> +#include <utility> +#include <map> +#include <fstream> +#include <sstream> + +#include "infomanager.hpp" +#include "twcommon.h" +#include "partitions.hpp" + +using namespace std; + +InfoManager::InfoManager(const string filename) { + File = filename; +} + +InfoManager::~InfoManager(void) { + mValues.clear(); +} + +int InfoManager::LoadValues(void) { + string str; + + // Read in the file, if possible + FILE* in = fopen(File.c_str(), "rb"); + if (!in) { + LOGINFO("InfoManager file '%s' not found.\n", File.c_str()); + return -1; + } else { + LOGINFO("InfoManager loading from '%s'.\n", File.c_str()); + } + + while (!feof(in)) { + string Name; + string Value; + unsigned short length; + char array[512]; + + if (fread(&length, 1, sizeof(unsigned short), in) != sizeof(unsigned short)) goto error; + if (length >= 512) goto error; + if (fread(array, 1, length, in) != length) goto error; + Name = array; + + if (fread(&length, 1, sizeof(unsigned short), in) != sizeof(unsigned short)) goto error; + if (length >= 512) goto error; + if (fread(array, 1, length, in) != length) goto error; + Value = array; + + map<string, string>::iterator pos; + + pos = mValues.find(Name); + if (pos != mValues.end()) { + pos->second = Value; + } else { + mValues.insert(make_pair(Name, Value)); + } + } +error: + fclose(in); + return 0; +} + +int InfoManager::SaveValues(void) { + if (File.empty()) + return -1; + + PartitionManager.Mount_By_Path(File, true); +LOGINFO("InfoManager saving '%s'\n", File.c_str()); + FILE* out = fopen(File.c_str(), "wb"); + if (!out) + return -1; + + map<string, string>::iterator iter; + for (iter = mValues.begin(); iter != mValues.end(); ++iter) { + unsigned short length = (unsigned short) iter->first.length() + 1; + fwrite(&length, 1, sizeof(unsigned short), out); + fwrite(iter->first.c_str(), 1, length, out); + length = (unsigned short) iter->second.length() + 1; + fwrite(&length, 1, sizeof(unsigned short), out); + fwrite(iter->second.c_str(), 1, length, out); + } + fclose(out); + return 0; +} + +int InfoManager::GetValue(const string varName, string& value) { + string localStr = varName; + + map<string, string>::iterator pos; + pos = mValues.find(localStr); + if (pos == mValues.end()) + return -1; + + value = pos->second; + return 0; +} + +int InfoManager::GetValue(const string varName, int& value) { + string data; + + if (GetValue(varName,data) != 0) + return -1; + + value = atoi(data.c_str()); + return 0; +} + +int InfoManager::GetValue(const string varName, float& value) { + string data; + + if (GetValue(varName,data) != 0) + return -1; + + value = atof(data.c_str()); + return 0; +} + +unsigned long long InfoManager::GetValue(const string varName, unsigned long long& value) { + string data; + + if (GetValue(varName,data) != 0) + return -1; + + value = strtoull(data.c_str(), NULL, 10); + return 0; +} + +// This function will return an empty string if the value doesn't exist +string InfoManager::GetStrValue(const string varName) { + string retVal; + + GetValue(varName, retVal); + return retVal; +} + +// This function will return 0 if the value doesn't exist +int InfoManager::GetIntValue(const string varName) { + string retVal; + GetValue(varName, retVal); + return atoi(retVal.c_str()); +} + +int InfoManager::SetValue(const string varName, string value) { + // Don't allow empty values or numerical starting values + if (varName.empty() || (varName[0] >= '0' && varName[0] <= '9')) + return -1; + + map<string, string>::iterator pos; + pos = mValues.find(varName); + if (pos == mValues.end()) + mValues.insert(make_pair(varName, value)); + else + pos->second = value; + + return 0; +} + +int InfoManager::SetValue(const string varName, int value) { + ostringstream valStr; + valStr << value; + return SetValue(varName, valStr.str()); +} + +int InfoManager::SetValue(const string varName, float value) { + ostringstream valStr; + valStr << value; + return SetValue(varName, valStr.str()); +} + +int InfoManager::SetValue(const string varName, unsigned long long value) { + ostringstream valStr; + valStr << value; + return SetValue(varName, valStr.str()); +} diff --git a/infomanager.hpp b/infomanager.hpp new file mode 100644 index 000000000..de8aef423 --- /dev/null +++ b/infomanager.hpp @@ -0,0 +1,58 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _INFOMANAGER_HPP_HEADER +#define _INFOMANAGER_HPP_HEADER + +#include <string> +#include <utility> +#include <map> + +using namespace std; + +class InfoManager +{ +public: + InfoManager(const string filename); + virtual ~InfoManager(); + int LoadValues(); + int SaveValues(); + + // Core get routines + int GetValue(const string varName, string& value); + int GetValue(const string varName, int& value); + int GetValue(const string varName, float& value); + unsigned long long GetValue(const string varName, unsigned long long& value); + + string GetStrValue(const string varName); + int GetIntValue(const string varName); + + // Core set routines + int SetValue(const string varName, string value); + int SetValue(const string varName, int value); + int SetValue(const string varName, float value); + int SetValue(const string varName, unsigned long long value); + +private: + string File; + map<string, string> mValues; + +}; + +#endif // _DATAMANAGER_HPP_HEADER + diff --git a/libtar/extract.c b/libtar/extract.c index 4526c98ee..e605aca43 100644 --- a/libtar/extract.c +++ b/libtar/extract.c @@ -94,7 +94,7 @@ tar_set_file_perms(TAR *t, char *realname) /* switchboard */ int -tar_extract_file(TAR *t, char *realname, char *prefix) +tar_extract_file(TAR *t, char *realname, char *prefix, const int *progress_fd) { int i; char *lnp; @@ -141,7 +141,7 @@ tar_extract_file(TAR *t, char *realname, char *prefix) } else /* if (TH_ISREG(t)) */ { printf("reg\n"); - i = tar_extract_regfile(t, realname); + i = tar_extract_regfile(t, realname, progress_fd); } if (i != 0) { @@ -189,7 +189,7 @@ tar_extract_file(TAR *t, char *realname, char *prefix) /* extract regular file */ int -tar_extract_regfile(TAR *t, char *realname) +tar_extract_regfile(TAR *t, char *realname, const int *progress_fd) { //mode_t mode; size_t size; @@ -285,6 +285,11 @@ tar_extract_regfile(TAR *t, char *realname) printf("### done extracting %s\n", filename); #endif + if (*progress_fd != 0) { + unsigned long long file_size = (unsigned long long)(size); + write(*progress_fd, &file_size, sizeof(file_size)); + } + return 0; } diff --git a/libtar/libtar.h b/libtar/libtar.h index 91523d043..e3154ae90 100644 --- a/libtar/libtar.h +++ b/libtar/libtar.h @@ -226,7 +226,7 @@ void th_finish(TAR *t); /***** extract.c ***********************************************************/ /* sequentially extract next file from t */ -int tar_extract_file(TAR *t, char *realname, char *prefix); +int tar_extract_file(TAR *t, char *realname, char *prefix, const int *progress_fd); /* extract different file types */ int tar_extract_dir(TAR *t, char *realname); @@ -237,7 +237,7 @@ int tar_extract_blockdev(TAR *t, char *realname); int tar_extract_fifo(TAR *t, char *realname); /* for regfiles, we need to extract the content blocks as well */ -int tar_extract_regfile(TAR *t, char *realname); +int tar_extract_regfile(TAR *t, char *realname, const int *progress_fd); int tar_skip_regfile(TAR *t); @@ -294,7 +294,7 @@ void int_to_oct_nonull(int num, char *oct, size_t octlen); /* extract groups of files */ int tar_extract_glob(TAR *t, char *globname, char *prefix); -int tar_extract_all(TAR *t, char *prefix); +int tar_extract_all(TAR *t, char *prefix, const int *progress_fd); /* add a whole tree of files */ int tar_append_tree(TAR *t, char *realdir, char *savedir, char *exclude); diff --git a/libtar/wrapper.c b/libtar/wrapper.c index 708c845b9..82f045f7d 100644 --- a/libtar/wrapper.c +++ b/libtar/wrapper.c @@ -27,7 +27,7 @@ tar_extract_glob(TAR *t, char *globname, char *prefix) { char *filename; char buf[MAXPATHLEN]; - int i; + int i, fd = 0; while ((i = th_read(t)) == 0) { @@ -44,7 +44,7 @@ tar_extract_glob(TAR *t, char *globname, char *prefix) snprintf(buf, sizeof(buf), "%s/%s", prefix, filename); else strlcpy(buf, filename, sizeof(buf)); - if (tar_extract_file(t, filename, prefix) != 0) + if (tar_extract_file(t, filename, prefix, &fd) != 0) return -1; } @@ -53,7 +53,7 @@ tar_extract_glob(TAR *t, char *globname, char *prefix) int -tar_extract_all(TAR *t, char *prefix) +tar_extract_all(TAR *t, char *prefix, const int *progress_fd) { char *filename; char buf[MAXPATHLEN]; @@ -80,7 +80,7 @@ tar_extract_all(TAR *t, char *prefix) "\"%s\")\n", buf); #endif printf("item name: '%s'\n", filename); - if (tar_extract_file(t, buf, prefix) != 0) + if (tar_extract_file(t, buf, prefix, progress_fd) != 0) return -1; } return (i == 1 ? 0 : -1); diff --git a/partition.cpp b/partition.cpp index 37654311b..1a62bbae8 100644 --- a/partition.cpp +++ b/partition.cpp @@ -41,6 +41,7 @@ #include "twrpTar.hpp" #include "twrpDU.hpp" #include "fixPermissions.hpp" +#include "infomanager.hpp" extern "C" { #include "mtdutils/mtdutils.h" #include "mtdutils/mounts.h" @@ -1284,9 +1285,9 @@ bool TWPartition::Repair() { return false; } -bool TWPartition::Backup(string backup_folder) { +bool TWPartition::Backup(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size) { if (Backup_Method == FILES) - return Backup_Tar(backup_folder); + return Backup_Tar(backup_folder, overall_size, other_backups_size); else if (Backup_Method == DD) return Backup_DD(backup_folder); else if (Backup_Method == FLASH_UTILS) @@ -1343,13 +1344,32 @@ bool TWPartition::Check_MD5(string restore_folder) { return false; } -bool TWPartition::Restore(string restore_folder) { - size_t first_period, second_period; +bool TWPartition::Restore(string restore_folder, const unsigned long long *total_restore_size, unsigned long long *already_restored_size) { string Restore_File_System; TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, "Restoring"); LOGINFO("Restore filename is: %s\n", Backup_FileName.c_str()); + Restore_File_System = Get_Restore_File_System(restore_folder); + + if (Is_File_System(Restore_File_System)) + return Restore_Tar(restore_folder, Restore_File_System, total_restore_size, already_restored_size); + else if (Is_Image(Restore_File_System)) { + *already_restored_size += TWFunc::Get_File_Size(Backup_Name); + if (Restore_File_System == "emmc") + return Restore_DD(restore_folder, total_restore_size, already_restored_size); + else if (Restore_File_System == "mtd" || Restore_File_System == "bml") + return Restore_Flash_Image(restore_folder, total_restore_size, already_restored_size); + } + + LOGERR("Unknown restore method for '%s'\n", Mount_Point.c_str()); + return false; +} + +string TWPartition::Get_Restore_File_System(string restore_folder) { + size_t first_period, second_period; + string Restore_File_System; + // Parse backup filename to extract the file system before wiping first_period = Backup_FileName.find("."); if (first_period == string::npos) { @@ -1364,18 +1384,7 @@ bool TWPartition::Restore(string restore_folder) { } Restore_File_System.resize(second_period); LOGINFO("Restore file system is: '%s'.\n", Restore_File_System.c_str()); - - if (Is_File_System(Restore_File_System)) - return Restore_Tar(restore_folder, Restore_File_System); - else if (Is_Image(Restore_File_System)) { - if (Restore_File_System == "emmc") - return Restore_DD(restore_folder); - else if (Restore_File_System == "mtd" || Restore_File_System == "bml") - return Restore_Flash_Image(restore_folder); - } - - LOGERR("Unknown restore method for '%s'\n", Mount_Point.c_str()); - return false; + return Restore_File_System; } string TWPartition::Backup_Method_By_Name() { @@ -1709,7 +1718,7 @@ bool TWPartition::Wipe_Data_Without_Wiping_Media() { #endif // ifdef TW_OEM_BUILD } -bool TWPartition::Backup_Tar(string backup_folder) { +bool TWPartition::Backup_Tar(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size) { char back_name[255], split_index[5]; string Full_FileName, Split_FileName, Tar_Args, Command; int use_compression, use_encryption = 0, index, backup_count; @@ -1749,7 +1758,9 @@ bool TWPartition::Backup_Tar(string backup_folder) { tar.setdir(Backup_Path); tar.setfn(Full_FileName); tar.setsize(Backup_Size); - if (tar.createTarFork() != 0) + tar.partition_name = Backup_Name; + tar.backup_folder = backup_folder; + if (tar.createTarFork(overall_size, other_backups_size) != 0) return false; return true; } @@ -1804,7 +1815,40 @@ bool TWPartition::Backup_Dump_Image(string backup_folder) { return true; } -bool TWPartition::Restore_Tar(string restore_folder, string Restore_File_System) { +unsigned long long TWPartition::Get_Restore_Size(string restore_folder) { + InfoManager restore_info(restore_folder + "/" + Backup_Name + ".info"); + if (restore_info.LoadValues() == 0) { + if (restore_info.GetValue("backup_size", Restore_Size) == 0) { + LOGINFO("Read info file, restore size is %llu\n", Restore_Size); + return Restore_Size; + } + } + string Full_FileName, Restore_File_System = Get_Restore_File_System(restore_folder); + + Full_FileName = restore_folder + "/" + Backup_FileName; + + if (Is_Image(Restore_File_System)) { + Restore_Size = TWFunc::Get_File_Size(Full_FileName); + return Restore_Size; + } + + twrpTar tar; + tar.setdir(Backup_Path); + tar.setfn(Full_FileName); + tar.backup_name = Backup_Name; +#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS + string Password; + DataManager::GetValue("tw_restore_password", Password); + if (!Password.empty()) + tar.setpassword(Password); +#endif + tar.partition_name = Backup_Name; + tar.backup_folder = restore_folder; + Restore_Size = tar.get_size(); + return Restore_Size; +} + +bool TWPartition::Restore_Tar(string restore_folder, string Restore_File_System, const unsigned long long *total_restore_size, unsigned long long *already_restored_size) { string Full_FileName, Command; int index = 0; char split_index[5]; @@ -1842,7 +1886,7 @@ bool TWPartition::Restore_Tar(string restore_folder, string Restore_File_System) if (!Password.empty()) tar.setpassword(Password); #endif - if (tar.extractTarFork() != 0) + if (tar.extractTarFork(total_restore_size, already_restored_size) != 0) ret = false; else ret = true; @@ -1868,8 +1912,10 @@ bool TWPartition::Restore_Tar(string restore_folder, string Restore_File_System) return ret; } -bool TWPartition::Restore_DD(string restore_folder) { +bool TWPartition::Restore_DD(string restore_folder, const unsigned long long *total_restore_size, unsigned long long *already_restored_size) { string Full_FileName, Command; + double display_percent, progress_percent; + char size_progress[1024]; TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, "Restoring"); Full_FileName = restore_folder + "/" + Backup_FileName; @@ -1890,11 +1936,19 @@ bool TWPartition::Restore_DD(string restore_folder) { Command = "dd bs=4096 if='" + Full_FileName + "' of=" + Actual_Block_Device; LOGINFO("Restore command: '%s'\n", Command.c_str()); TWFunc::Exec_Cmd(Command); + display_percent = (double)(Restore_Size + *already_restored_size) / (double)(*total_restore_size) * 100; + sprintf(size_progress, "%lluMB of %lluMB, %i%%", (Restore_Size + *already_restored_size) / 1048576, *total_restore_size / 1048576, (int)(display_percent)); + DataManager::SetValue("tw_size_progress", size_progress); + progress_percent = (display_percent / 100); + DataManager::SetProgress((float)(progress_percent)); + *already_restored_size += Restore_Size; return true; } -bool TWPartition::Restore_Flash_Image(string restore_folder) { +bool TWPartition::Restore_Flash_Image(string restore_folder, const unsigned long long *total_restore_size, unsigned long long *already_restored_size) { string Full_FileName, Command; + double display_percent, progress_percent; + char size_progress[1024]; gui_print("Restoring %s...\n", Display_Name.c_str()); Full_FileName = restore_folder + "/" + Backup_FileName; @@ -1905,6 +1959,12 @@ bool TWPartition::Restore_Flash_Image(string restore_folder) { Command = "flash_image " + MTD_Name + " '" + Full_FileName + "'"; LOGINFO("Restore command: '%s'\n", Command.c_str()); TWFunc::Exec_Cmd(Command); + display_percent = (double)(Restore_Size + *already_restored_size) / (double)(*total_restore_size) * 100; + sprintf(size_progress, "%lluMB of %lluMB, %i%%", (Restore_Size + *already_restored_size) / 1048576, *total_restore_size / 1048576, (int)(display_percent)); + DataManager::SetValue("tw_size_progress", size_progress); + progress_percent = (display_percent / 100); + DataManager::SetProgress((float)(progress_percent)); + *already_restored_size += Restore_Size; return true; } diff --git a/partitionmanager.cpp b/partitionmanager.cpp index df623fa83..de727f4a2 100644 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -599,6 +599,7 @@ bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folde unsigned long total_time, remain_time, section_time; int use_compression, backup_time; float pos; + unsigned long long total_size, current_size; if (Part == NULL) return true; @@ -615,7 +616,10 @@ bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folde total_time = (*img_bytes / (unsigned long)img_bps) + (*file_bytes / (unsigned long)file_bps); remain_time = (*img_bytes_remaining / (unsigned long)img_bps) + (*file_bytes_remaining / (unsigned long)file_bps); - pos = (total_time - remain_time) / (float) total_time; + //pos = (total_time - remain_time) / (float) total_time; + total_size = *file_bytes + *img_bytes; + current_size = *file_bytes + *img_bytes - *file_bytes_remaining - *img_bytes_remaining; + pos = ((float)(current_size) / (float)(total_size)); DataManager::SetProgress(pos); LOGINFO("Estimated total time: %lu\nEstimated remaining time: %lu\n", total_time, remain_time); @@ -628,17 +632,20 @@ bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folde // Set the position pos = section_time / (float) total_time; - DataManager::ShowProgress(pos, section_time); + //DataManager::ShowProgress(pos, section_time); time(&start); - if (Part->Backup(Backup_Folder)) { + if (Part->Backup(Backup_Folder, &total_size, ¤t_size)) { + current_size += Part->Backup_Size; + pos = (float)((float)(current_size) / (float)(total_size)); + DataManager::SetProgress(pos); if (Part->Has_SubPartition) { std::vector<TWPartition*>::iterator subpart; for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) { if ((*subpart)->Can_Be_Backed_Up && (*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) { - if (!(*subpart)->Backup(Backup_Folder)) + if (!(*subpart)->Backup(Backup_Folder, &total_size, ¤t_size)) return false; sync(); sync(); @@ -649,6 +656,9 @@ bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folde } else { *img_bytes_remaining -= (*subpart)->Backup_Size; } + current_size += Part->Backup_Size; + pos = (float)(current_size / total_size); + DataManager::SetProgress(pos); } } } @@ -833,18 +843,18 @@ int TWPartitionManager::Run_Backup(void) { return true; } -bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name, int partition_count) { +bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name, int partition_count, const unsigned long long *total_restore_size, unsigned long long *already_restored_size) { time_t Start, Stop; time(&Start); - DataManager::ShowProgress(1.0 / (float)partition_count, 150); - if (!Part->Restore(Restore_Name)) + //DataManager::ShowProgress(1.0 / (float)partition_count, 150); + if (!Part->Restore(Restore_Name, total_restore_size, already_restored_size)) return false; 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) { - if (!(*subpart)->Restore(Restore_Name)) + if (!(*subpart)->Restore(Restore_Name, total_restore_size, already_restored_size)) return false; } } @@ -861,6 +871,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { time(&rStart); string Restore_List, restore_path; size_t start_pos = 0, end_pos; + unsigned long long total_restore_size = 0, already_restored_size = 0; gui_print("\n[RESTORE STARTED]\n\n"); gui_print("Restore folder: '%s'\n", Restore_Name.c_str()); @@ -876,6 +887,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { } else { gui_print("Skipping MD5 check based on user setting.\n"); } + gui_print("Calculating restore details...\n"); DataManager::GetValue("tw_restore_selected", Restore_List); if (!Restore_List.empty()) { end_pos = Restore_List.find(";", start_pos); @@ -886,6 +898,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { partition_count++; if (check_md5 > 0 && !restore_part->Check_MD5(Restore_Name)) return false; + total_restore_size += restore_part->Get_Restore_Size(Restore_Name); if (restore_part->Has_SubPartition) { std::vector<TWPartition*>::iterator subpart; @@ -893,6 +906,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_part->Mount_Point) { if (check_md5 > 0 && !(*subpart)->Check_MD5(Restore_Name)) return false; + total_restore_size += (*subpart)->Get_Restore_Size(Restore_Name); } } } @@ -910,7 +924,9 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { } gui_print("Restoring %i partitions...\n", partition_count); + gui_print("Total restore size is %lluMB\n", total_restore_size / 1048576); DataManager::SetProgress(0.0); + start_pos = 0; if (!Restore_List.empty()) { end_pos = Restore_List.find(";", start_pos); @@ -919,7 +935,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { restore_part = Find_Partition_By_Path(restore_path); if (restore_part != NULL) { partition_count++; - if (!Restore_Partition(restore_part, Restore_Name, partition_count)) + if (!Restore_Partition(restore_part, Restore_Name, partition_count, &total_restore_size, &already_restored_size)) return false; } else { LOGERR("Unable to locate '%s' partition for restoring.\n", restore_path.c_str()); @@ -933,6 +949,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { UnMount_Main_Partitions(); time(&rStop); gui_print_color("highlight", "[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart)); + DataManager::SetValue("tw_file_progress", ""); return true; } diff --git a/partitions.hpp b/partitions.hpp index 73ff1fbc5..0d74315b4 100644 --- a/partitions.hpp +++ b/partitions.hpp @@ -57,9 +57,10 @@ public: bool Wipe_AndSec(); // Wipes android secure bool Can_Repair(); // Checks to see if we have everything needed to be able to repair the current file system bool Repair(); // Repairs the current file system - bool Backup(string backup_folder); // Backs up the partition to the folder specified + bool Backup(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size); // Backs up the partition to the folder specified bool Check_MD5(string restore_folder); // Checks MD5 of a backup - bool Restore(string restore_folder); // Restores the partition using the backup folder provided + bool Restore(string restore_folder, const unsigned long long *total_restore_size, unsigned long long *already_restored_size); // Restores the partition using the backup folder provided + unsigned long long Get_Restore_Size(string restore_folder); // Returns the overall restore size of the backup string Backup_Method_By_Name(); // Returns a string of the backup method for human readable output bool Decrypt(string Password); // Decrypts the partition, return 0 for failure and -1 for success bool Wipe_Encryption(); // Ignores wipe commands for /data/media devices and formats the original block device @@ -94,12 +95,13 @@ private: bool Wipe_RMRF(); // Uses rm -rf to wipe bool Wipe_F2FS(); // Uses mkfs.f2fs to wipe bool Wipe_Data_Without_Wiping_Media(); // Uses rm -rf to wipe but does not wipe /data/media - bool Backup_Tar(string backup_folder); // Backs up using tar for file systems + bool Backup_Tar(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size); // Backs up using tar for file systems bool Backup_DD(string backup_folder); // Backs up using dd for emmc memory types bool Backup_Dump_Image(string backup_folder); // Backs up using dump_image for MTD memory types - bool Restore_Tar(string restore_folder, string Restore_File_System); // 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 + string Get_Restore_File_System(string restore_folder); // Returns the file system that was in place at the time of the backup + bool Restore_Tar(string restore_folder, string Restore_File_System, const unsigned long long *total_restore_size, unsigned long long *already_restored_size); // Restore using tar for file systems + bool Restore_DD(string restore_folder, const unsigned long long *total_restore_size, unsigned long long *already_restored_size); // Restore using dd for emmc memory types + bool Restore_Flash_Image(string restore_folder, const unsigned long long *total_restore_size, unsigned long long *already_restored_size); // 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 bool Make_Dir(string Path, bool Display_Error); // Creates a directory if it doesn't already exist @@ -131,6 +133,7 @@ private: unsigned long long Used; // Overall used space unsigned long long Free; // Overall free space unsigned long long Backup_Size; // Backup size -- may be different than used space especially when /data/media is present + unsigned long long Restore_Size; // Restore size of the current restore operation bool Can_Be_Encrypted; // This partition might be encrypted, affects error handling, can only be true if crypto support is compiled in bool Is_Encrypted; // This partition is thought to be encrypted -- it wouldn't mount for some reason, only avialble with crypto support bool Is_Decrypted; // This partition has successfully been decrypted @@ -227,7 +230,7 @@ private: void Setup_Android_Secure_Location(TWPartition* Part); // Sets up .android_secure if needed bool Make_MD5(bool generate_md5, string Backup_Folder, string Backup_Filename); // Generates an MD5 after a backup is made bool Backup_Partition(TWPartition* Part, string Backup_Folder, bool generate_md5, unsigned long long* img_bytes_remaining, unsigned long long* file_bytes_remaining, unsigned long *img_time, unsigned long *file_time, unsigned long long *img_bytes, unsigned long long *file_bytes); - bool Restore_Partition(TWPartition* Part, string Restore_Name, int partition_count); + bool Restore_Partition(TWPartition* Part, string Restore_Name, int partition_count, const unsigned long long *total_restore_size, unsigned long long *already_restored_size); void Output_Partition(TWPartition* Part); TWPartition* Find_Next_Storage(string Path, string Exclude); int Open_Lun_File(string Partition_Path, string Lun_File); diff --git a/twrp-functions.cpp b/twrp-functions.cpp index 2128c9635..db98a363a 100644 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -299,6 +299,30 @@ std::string TWFunc::Remove_Trailing_Slashes(const std::string& path, bool leaveL return res; } +vector<string> TWFunc::split_string(const string &in, char del, bool skip_empty) { + vector<string> res; + + if (in.empty() || del == '\0') + return res; + + string field; + istringstream f(in); + if (del == '\n') { + while(getline(f, field)) { + if (field.empty() && skip_empty) + continue; + res.push_back(field); + } + } else { + while(getline(f, field, del)) { + if (field.empty() && skip_empty) + continue; + res.push_back(field); + } + } + return res; +} + #ifndef BUILD_TWRPTAR_MAIN // Returns "/path" from a full /path/to/file.name diff --git a/twrp-functions.hpp b/twrp-functions.hpp index ff1176389..284a29783 100644 --- a/twrp-functions.hpp +++ b/twrp-functions.hpp @@ -50,6 +50,7 @@ public: static int Try_Decrypting_File(string fn, string password); // -1 for some error, 0 for failed to decrypt, 1 for decrypted, 3 for decrypted and found gzip format static unsigned long Get_File_Size(string Path); // Returns the size of a file static std::string Remove_Trailing_Slashes(const std::string& path, bool leaveLast = false); // Normalizes the path, e.g /data//media/ -> /data/media + static vector<string> split_string(const string &in, char del, bool skip_empty); #ifndef BUILD_TWRPTAR_MAIN static void install_htc_dumlock(void); // Installs HTC Dumlock diff --git a/twrpTar.cpp b/twrpTar.cpp index 7f00da5c7..28ac91ac1 100644 --- a/twrpTar.cpp +++ b/twrpTar.cpp @@ -40,6 +40,10 @@ extern "C" { #include "twcommon.h" #include "variables.h" #include "twrp-functions.hpp" +#ifndef BUILD_TWRPTAR_MAIN +#include "data.hpp" +#include "infomanager.hpp" +#endif //ndef BUILD_TWRPTAR_MAIN using namespace std; @@ -75,20 +79,35 @@ void twrpTar::setpassword(string pass) { password = pass; } -int twrpTar::createTarFork() { +int twrpTar::createTarFork(const unsigned long long *overall_size, const unsigned long long *other_backups_size) { int status = 0; pid_t pid, rc_pid; + int progress_pipe[2], ret; + + file_count = 0; + + if (pipe(progress_pipe) < 0) { + LOGERR("Error creating progress tracking pipe\n"); + return -1; + } if ((pid = fork()) == -1) { LOGINFO("create tar failed to fork.\n"); + close(progress_pipe[0]); + close(progress_pipe[1]); return -1; } if (pid == 0) { // Child process + + // Child closes input side of progress pipe + close(progress_pipe[0]); + progress_pipe_fd = progress_pipe[1]; + if (use_encryption || userdata_encryption) { LOGINFO("Using encryption\n"); DIR* d; struct dirent* de; - unsigned long long regular_size = 0, encrypt_size = 0, target_size = 0, core_count = 1; + unsigned long long regular_size = 0, encrypt_size = 0, target_size = 0, core_count = 1, total_size; unsigned enc_thread_id = 1, regular_thread_id = 0, i, start_thread_id = 1; int item_len, ret, thread_error = 0; std::vector<TarListStruct> RegularList; @@ -110,6 +129,7 @@ int twrpTar::createTarFork() { d = opendir(tardir.c_str()); if (d == NULL) { LOGERR("error opening '%s'\n", tardir.c_str()); + close(progress_pipe[1]); _exit(-1); } // Figure out the size of all data to be encrypted and create a list of unencrypted files @@ -121,11 +141,15 @@ int twrpTar::createTarFork() { if (de->d_type == DT_DIR) { item_len = strlen(de->d_name); if (userdata_encryption && ((item_len >= 3 && strncmp(de->d_name, "app", 3) == 0) || (item_len >= 6 && strncmp(de->d_name, "dalvik", 6) == 0))) { - if (Generate_TarList(FileName, &RegularList, &target_size, ®ular_thread_id) < 0) { + ret = Generate_TarList(FileName, &RegularList, &target_size, ®ular_thread_id); + if (ret < 0) { LOGERR("Error in Generate_TarList with regular list!\n"); closedir(d); + close(progress_pipe_fd); + close(progress_pipe[1]); _exit(-1); } + file_count = (unsigned long long)(ret); regular_size += du.Get_Folder_Size(FileName); } else { encrypt_size += du.Get_Folder_Size(FileName); @@ -152,6 +176,7 @@ int twrpTar::createTarFork() { d = opendir(tardir.c_str()); if (d == NULL) { LOGERR("error opening '%s'\n", tardir.c_str()); + close(progress_pipe[1]); _exit(-1); } // Divide up the encrypted file list for threading @@ -166,11 +191,14 @@ int twrpTar::createTarFork() { // Do nothing, we added these to RegularList earlier } else { FileName = tardir + "/" + de->d_name; - if (Generate_TarList(FileName, &EncryptList, &target_size, &enc_thread_id) < 0) { + ret = Generate_TarList(FileName, &EncryptList, &target_size, &enc_thread_id); + if (ret < 0) { LOGERR("Error in Generate_TarList with encrypted list!\n"); closedir(d); + close(progress_pipe[1]); _exit(-1); } + file_count += (unsigned long long)(ret); } } else if (de->d_type == DT_REG || de->d_type == DT_LNK) { stat(FileName.c_str(), &st); @@ -179,17 +207,26 @@ int twrpTar::createTarFork() { TarItem.fn = FileName; TarItem.thread_id = enc_thread_id; EncryptList.push_back(TarItem); + file_count++; } } closedir(d); if (enc_thread_id != core_count) { LOGERR("Error dividing up threads for encryption, %i threads for %i cores!\n", enc_thread_id, core_count); - if (enc_thread_id > core_count) + if (enc_thread_id > core_count) { + close(progress_pipe[1]); _exit(-1); - else + } else { LOGERR("Continuining anyway."); + } } + // Send file count to parent + write(progress_pipe_fd, &file_count, sizeof(file_count)); + // Send backup size to parent + total_size = regular_size + encrypt_size; + write(progress_pipe_fd, &total_size, sizeof(total_size)); + if (userdata_encryption) { // Create a backup of unencrypted data reg.setfn(tarfn); @@ -198,23 +235,28 @@ int twrpTar::createTarFork() { reg.use_encryption = 0; reg.use_compression = use_compression; reg.split_archives = 1; + reg.progress_pipe_fd = progress_pipe_fd; LOGINFO("Creating unencrypted backup...\n"); if (createList((void*)®) != 0) { LOGERR("Error creating unencrypted backup.\n"); + close(progress_pipe[1]); _exit(-1); } } if (pthread_attr_init(&tattr)) { LOGERR("Unable to pthread_attr_init\n"); + close(progress_pipe[1]); _exit(-1); } if (pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE)) { LOGERR("Error setting pthread_attr_setdetachstate\n"); + close(progress_pipe[1]); _exit(-1); } if (pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM)) { LOGERR("Error setting pthread_attr_setscope\n"); + close(progress_pipe[1]); _exit(-1); } /*if (pthread_attr_setstacksize(&tattr, 524288)) { @@ -232,12 +274,14 @@ int twrpTar::createTarFork() { enc[i].setpassword(password); enc[i].use_compression = use_compression; enc[i].split_archives = 1; + enc[i].progress_pipe_fd = progress_pipe_fd; LOGINFO("Start encryption thread %i\n", i); ret = pthread_create(&enc_thread[i], &tattr, createList, (void*)&enc[i]); if (ret) { - LOGINFO("Unable to create %i thread for encryption! %i\nContinuing in same thread (backup will be slower).", i, ret); + LOGINFO("Unable to create %i thread for encryption! %i\nContinuing in same thread (backup will be slower).\n", i, ret); if (createList((void*)&enc[i]) != 0) { LOGERR("Error creating encrypted backup %i.\n", i); + close(progress_pipe[1]); _exit(-1); } else { enc[i].thread_id = i + 1; @@ -252,6 +296,7 @@ int twrpTar::createTarFork() { if (enc[i].thread_id == i) { if (pthread_join(enc_thread[i], &thread_return)) { LOGERR("Error joining thread %i\n", i); + close(progress_pipe[1]); _exit(-1); } else { LOGINFO("Joined thread %i.\n", i); @@ -259,6 +304,7 @@ int twrpTar::createTarFork() { if (ret != 0) { thread_error = 1; LOGERR("Thread %i returned an error %i.\n", i, ret); + close(progress_pipe[1]); _exit(-1); } } @@ -268,21 +314,28 @@ int twrpTar::createTarFork() { } if (thread_error) { LOGERR("Error returned by one or more threads.\n"); + close(progress_pipe[1]); _exit(-1); } LOGINFO("Finished encrypted backup.\n"); + close(progress_pipe[1]); _exit(0); } else { + // Not encrypted std::vector<TarListStruct> FileList; unsigned thread_id = 0; unsigned long long target_size = 0; twrpTar reg; + int ret; // Generate list of files to back up - if (Generate_TarList(tardir, &FileList, &target_size, &thread_id) < 0) { + ret = Generate_TarList(tardir, &FileList, &target_size, &thread_id); + if (ret < 0) { LOGERR("Error in Generate_TarList!\n"); + close(progress_pipe[1]); _exit(-1); } + file_count = (unsigned long long)(ret); // Create a backup reg.setfn(tarfn); reg.ItemList = &FileList; @@ -290,6 +343,7 @@ int twrpTar::createTarFork() { reg.use_encryption = 0; reg.use_compression = use_compression; reg.setsize(Total_Backup_Size); + reg.progress_pipe_fd = progress_pipe_fd; if (Total_Backup_Size > MAX_ARCHIVE_SIZE) { gui_print("Breaking backup file into multiple archives...\n"); reg.split_archives = 1; @@ -297,28 +351,96 @@ int twrpTar::createTarFork() { reg.split_archives = 0; } LOGINFO("Creating backup...\n"); + write(progress_pipe_fd, &file_count, sizeof(file_count)); + write(progress_pipe_fd, &Total_Backup_Size, sizeof(Total_Backup_Size)); if (createList((void*)®) != 0) { LOGERR("Error creating backup.\n"); + close(progress_pipe[1]); _exit(-1); } + close(progress_pipe[1]); _exit(0); } } else { + // Parent side + unsigned long long fs, size_backup, files_backup, total_backup_size; + int first_data = 0; + double display_percent, progress_percent; + char file_progress[1024]; + char size_progress[1024]; + files_backup = 0; + size_backup = 0; + + // Parent closes output side + close(progress_pipe[1]); + + // Read progress data from children + while (read(progress_pipe[0], &fs, sizeof(fs)) > 0) { + if (first_data == 0) { + // First incoming data is the file count + file_count = fs; + if (file_count == 0) file_count = 1; // prevent division by 0 below + first_data = 1; + } else if (first_data == 1) { + // Second incoming data is total size + total_backup_size = fs; + first_data = 2; + } else { + files_backup++; + size_backup += fs; + display_percent = (double)(files_backup) / (double)(file_count) * 100; + sprintf(file_progress, "%llu of %llu files, %i%%", files_backup, file_count, (int)(display_percent)); +#ifndef BUILD_TWRPTAR_MAIN + DataManager::SetValue("tw_file_progress", file_progress); + display_percent = (double)(size_backup + *other_backups_size) / (double)(*overall_size) * 100; + sprintf(size_progress, "%lluMB of %lluMB, %i%%", (size_backup + *other_backups_size) / 1048576, *overall_size / 1048576, (int)(display_percent)); + DataManager::SetValue("tw_size_progress", size_progress); + progress_percent = (display_percent / 100); + DataManager::SetProgress((float)(progress_percent)); +#endif //ndef BUILD_TWRPTAR_MAIN + } + } + close(progress_pipe[0]); +#ifndef BUILD_TWRPTAR_MAIN + DataManager::SetValue("tw_file_progress", ""); + DataManager::SetValue("tw_size_progress", ""); + + InfoManager backup_info(backup_folder + partition_name + ".info"); + backup_info.SetValue("backup_size", size_backup); + if (use_compression && use_encryption) + backup_info.SetValue("backup_type", 3); + else if (use_encryption) + backup_info.SetValue("backup_type", 2); + else if (use_compression) + backup_info.SetValue("backup_type", 1); + else + backup_info.SetValue("backup_type", 0); + backup_info.SetValue("file_count", files_backup); + backup_info.SaveValues(); +#endif //ndef BUILD_TWRPTAR_MAIN if (TWFunc::Wait_For_Child(pid, &status, "createTarFork()") != 0) return -1; } return 0; } -int twrpTar::extractTarFork() { +int twrpTar::extractTarFork(const unsigned long long *overall_size, unsigned long long *other_backups_size) { int status = 0; pid_t pid, rc_pid; + int progress_pipe[2], ret; + + if (pipe(progress_pipe) < 0) { + LOGERR("Error creating progress tracking pipe\n"); + return -1; + } pid = fork(); if (pid >= 0) // fork was successful { if (pid == 0) // child process { + close(progress_pipe[0]); + progress_pipe_fd = progress_pipe[1]; if (TWFunc::Path_Exists(tarfn)) { LOGINFO("Single archive\n"); if (extract() != 0) @@ -340,14 +462,17 @@ int twrpTar::extractTarFork() { tarfn += "000"; if (!TWFunc::Path_Exists(tarfn)) { LOGERR("Unable to locate '%s' or '%s'\n", basefn.c_str(), tarfn.c_str()); + close(progress_pipe_fd); _exit(-1); } if (TWFunc::Get_File_Type(tarfn) != 2) { LOGINFO("First tar file '%s' not encrypted\n", tarfn.c_str()); tars[0].basefn = basefn; tars[0].thread_id = 0; + tars[0].progress_pipe_fd = progress_pipe_fd; if (extractMulti((void*)&tars[0]) != 0) { LOGERR("Error extracting split archive.\n"); + close(progress_pipe_fd); _exit(-1); } } else { @@ -356,18 +481,22 @@ int twrpTar::extractTarFork() { // Start threading encrypted restores if (pthread_attr_init(&tattr)) { LOGERR("Unable to pthread_attr_init\n"); + close(progress_pipe_fd); _exit(-1); } if (pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE)) { LOGERR("Error setting pthread_attr_setdetachstate\n"); + close(progress_pipe_fd); _exit(-1); } if (pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM)) { LOGERR("Error setting pthread_attr_setscope\n"); + close(progress_pipe_fd); _exit(-1); } /*if (pthread_attr_setstacksize(&tattr, 524288)) { LOGERR("Error setting pthread_attr_setstacksize\n"); + close(progress_pipe_fd); _exit(-1); }*/ for (i = start_thread_id; i < 9; i++) { @@ -377,12 +506,14 @@ int twrpTar::extractTarFork() { tars[i].basefn = basefn; tars[i].setpassword(password); tars[i].thread_id = i; + tars[i].progress_pipe_fd = progress_pipe_fd; LOGINFO("Creating extract thread ID %i\n", i); ret = pthread_create(&tar_thread[i], &tattr, extractMulti, (void*)&tars[i]); if (ret) { - LOGINFO("Unable to create %i thread for extraction! %i\nContinuing in same thread (restore will be slower).", i, ret); + LOGINFO("Unable to create %i thread for extraction! %i\nContinuing in same thread (restore will be slower).\n", i, ret); if (extractMulti((void*)&tars[i]) != 0) { LOGERR("Error extracting backup in thread %i.\n", i); + close(progress_pipe_fd); _exit(-1); } else { tars[i].thread_id = i + 1; @@ -397,6 +528,7 @@ int twrpTar::extractTarFork() { if (tars[i].thread_id == i) { if (pthread_join(tar_thread[i], &thread_return)) { LOGERR("Error joining thread %i\n", i); + close(progress_pipe_fd); _exit(-1); } else { LOGINFO("Joined thread %i.\n", i); @@ -404,6 +536,7 @@ int twrpTar::extractTarFork() { if (ret != 0) { thread_error = 1; LOGERR("Thread %i returned an error %i.\n", i, ret); + close(progress_pipe_fd); _exit(-1); } } @@ -413,20 +546,49 @@ int twrpTar::extractTarFork() { } if (thread_error) { LOGERR("Error returned by one or more threads.\n"); + close(progress_pipe_fd); _exit(-1); } - LOGINFO("Finished encrypted backup.\n"); + LOGINFO("Finished encrypted restore.\n"); + close(progress_pipe_fd); _exit(0); } } else // parent process { + unsigned long long fs, size_backup; + double display_percent, progress_percent; + char size_progress[1024]; + size_backup = 0; + + // Parent closes output side + close(progress_pipe[1]); + + // Read progress data from children + while (read(progress_pipe[0], &fs, sizeof(fs)) > 0) { + size_backup += fs; + display_percent = (double)(size_backup + *other_backups_size) / (double)(*overall_size) * 100; + sprintf(size_progress, "%lluMB of %lluMB, %i%%", (size_backup + *other_backups_size) / 1048576, *overall_size / 1048576, (int)(display_percent)); + progress_percent = (display_percent / 100); +#ifndef BUILD_TWRPTAR_MAIN + DataManager::SetValue("tw_size_progress", size_progress); + DataManager::SetProgress((float)(progress_percent)); +#endif //ndef BUILD_TWRPTAR_MAIN + } + close(progress_pipe[0]); +#ifndef BUILD_TWRPTAR_MAIN + DataManager::SetValue("tw_file_progress", ""); +#endif //ndef BUILD_TWRPTAR_MAIN + *other_backups_size += size_backup; + if (TWFunc::Wait_For_Child(pid, &status, "extractTarFork()") != 0) return -1; } } else // fork has failed { + close(progress_pipe[0]); + close(progress_pipe[1]); LOGINFO("extract tar failed to fork.\n"); return -1; } @@ -440,6 +602,8 @@ int twrpTar::Generate_TarList(string Path, std::vector<TarListStruct> *TarList, string FileName; struct TarListStruct TarItem; string::size_type i; + int ret, file_count; + file_count = 0; d = opendir(Path.c_str()); if (d == NULL) { @@ -456,13 +620,17 @@ int twrpTar::Generate_TarList(string Path, std::vector<TarListStruct> *TarList, TarItem.thread_id = *thread_id; if (de->d_type == DT_DIR) { TarList->push_back(TarItem); - if (Generate_TarList(FileName, TarList, Target_Size, thread_id) < 0) + ret = Generate_TarList(FileName, TarList, Target_Size, thread_id); + if (ret < 0) return -1; + file_count += ret; } else if (de->d_type == DT_REG || de->d_type == DT_LNK) { stat(FileName.c_str(), &st); TarList->push_back(TarItem); - if (de->d_type == DT_REG) + if (de->d_type == DT_REG) { + file_count++; Archive_Current_Size += st.st_size; + } if (Archive_Current_Size != 0 && *Target_Size != 0 && Archive_Current_Size > *Target_Size) { *thread_id = *thread_id + 1; Archive_Current_Size = 0; @@ -470,14 +638,14 @@ int twrpTar::Generate_TarList(string Path, std::vector<TarListStruct> *TarList, } } closedir(d); - return 0; + return file_count; } int twrpTar::extractTar() { char* charRootDir = (char*) tardir.c_str(); if (openTar() == -1) return -1; - if (tar_extract_all(t, charRootDir) != 0) { + if (tar_extract_all(t, charRootDir, &progress_pipe_fd) != 0) { LOGERR("Unable to extract tar archive '%s'\n", tarfn.c_str()); return -1; } @@ -525,6 +693,7 @@ int twrpTar::tarList(std::vector<TarListStruct> *TarList, unsigned thread_id) { string temp; char actual_filename[PATH_MAX]; char *ptr; + unsigned long long fs; if (split_archives) { basefn = tarfn; @@ -547,7 +716,8 @@ int twrpTar::tarList(std::vector<TarListStruct> *TarList, unsigned thread_id) { strcpy(buf, TarList->at(i).fn.c_str()); lstat(buf, &st); if (S_ISREG(st.st_mode)) { // item is a regular file - if (split_archives && Archive_Current_Size + (unsigned long long)(st.st_size) > MAX_ARCHIVE_SIZE) { + fs = (unsigned long long)(st.st_size); + if (split_archives && Archive_Current_Size + fs > MAX_ARCHIVE_SIZE) { if (closeTar() != 0) { LOGERR("Error closing '%s' on thread %i\n", tarfn.c_str(), thread_id); return -3; @@ -566,7 +736,8 @@ int twrpTar::tarList(std::vector<TarListStruct> *TarList, unsigned thread_id) { } Archive_Current_Size = 0; } - Archive_Current_Size += (unsigned long long)(st.st_size); + Archive_Current_Size += fs; + write(progress_pipe_fd, &fs, sizeof(fs)); } LOGINFO("addFile '%s' including root: %i\n", buf, include_root_dir); if (addFile(buf, include_root_dir) != 0) { @@ -1106,6 +1277,116 @@ int twrpTar::entryExists(string entry) { return ret; } +unsigned long long twrpTar::get_size() { + if (TWFunc::Path_Exists(tarfn)) { + LOGINFO("Single archive\n"); + int type = 0; + return uncompressedSize(tarfn, &type); + } else { + LOGINFO("Multiple archives\n"); + string temp; + char actual_filename[255]; + int archive_count = 0, i, type = 0, temp_type = 0; + unsigned long long total_restore_size = 0; + + basefn = tarfn; + temp = basefn + "%i%02i"; + tarfn += "000"; + thread_id = 0; + sprintf(actual_filename, temp.c_str(), thread_id, archive_count); + if (!TWFunc::Path_Exists(actual_filename)) { + LOGERR("Unable to locate '%s' or '%s'\n", basefn.c_str(), tarfn.c_str()); + return 0; + } + for (i = 0; i < 9; i++) { + archive_count = 0; + sprintf(actual_filename, temp.c_str(), i, archive_count); + while (TWFunc::Path_Exists(actual_filename)) { + total_restore_size += uncompressedSize(actual_filename, &temp_type); + if (temp_type > type) + type = temp_type; + archive_count++; + if (archive_count > 99) + break; + sprintf(actual_filename, temp.c_str(), i, archive_count); + } + } +#ifndef BUILD_TWRPTAR_MAIN + InfoManager backup_info(backup_folder + "/" + partition_name + ".info"); + backup_info.SetValue("backup_size", total_restore_size); + backup_info.SetValue("backup_type", type); + backup_info.SaveValues(); +#endif //ndef BUILD_TWRPTAR_MAIN + return total_restore_size; + } + return 0; +} + +unsigned long long twrpTar::uncompressedSize(string filename, int *archive_type) { + int type = 0; + unsigned long long total_size = 0; + string Tar, Command, result; + vector<string> split; + + Tar = TWFunc::Get_Filename(filename); + type = TWFunc::Get_File_Type(filename); + if (type == 0) { + total_size = TWFunc::Get_File_Size(filename); + *archive_type = 0; + } else if (type == 1) { + // Compressed + Command = "pigz -l '" + filename + "'"; + /* if we set Command = "pigz -l " + tarfn + " | sed '1d' | cut -f5 -d' '"; + we get the uncompressed size at once. */ + TWFunc::Exec_Cmd(Command, result); + if (!result.empty()) { + /* Expected output: + compressed original reduced name + 95855838 179403776 -1.3% data.yaffs2.win + ^ + split[5] + */ + split = TWFunc::split_string(result, ' ', true); + if (split.size() > 4) + total_size = atoi(split[5].c_str()); + } + *archive_type = 1; + } else if (type == 2) { + // File is encrypted and may be compressed + int ret = TWFunc::Try_Decrypting_File(filename, password); + *archive_type = 2; + if (ret < 1) { + LOGERR("Failed to decrypt tar file '%s'\n", filename.c_str()); + total_size = TWFunc::Get_File_Size(filename); + } else if (ret == 1) { + LOGERR("Decrypted file is not in tar format.\n"); + total_size = TWFunc::Get_File_Size(filename); + } else if (ret == 3) { + *archive_type = 3; + Command = "openaes dec --key \"" + password + "\" --in '" + filename + "' | pigz -l"; + /* if we set Command = "pigz -l " + tarfn + " | sed '1d' | cut -f5 -d' '"; + we get the uncompressed size at once. */ + TWFunc::Exec_Cmd(Command, result); + if (!result.empty()) { + LOGINFO("result was: '%s'\n", result.c_str()); + /* Expected output: + compressed original reduced name + 95855838 179403776 -1.3% data.yaffs2.win + ^ + split[5] + */ + split = TWFunc::split_string(result, ' ', true); + if (split.size() > 4) + total_size = atoi(split[5].c_str()); + } + } else { + total_size = TWFunc::Get_File_Size(filename); + } + } + + return total_size; +} + extern "C" ssize_t write_tar(int fd, const void *buffer, size_t size) { return (ssize_t) write_libtar_buffer(fd, buffer, size); } diff --git a/twrpTar.hpp b/twrpTar.hpp index 443e5f4b3..799475234 100644 --- a/twrpTar.hpp +++ b/twrpTar.hpp @@ -45,12 +45,13 @@ class twrpTar { public: twrpTar(); virtual ~twrpTar(); - int createTarFork(); - int extractTarFork(); + int createTarFork(const unsigned long long *overall_size, const unsigned long long *other_backups_size); + int extractTarFork(const unsigned long long *overall_size, unsigned long long *other_backups_size); void setfn(string fn); void setdir(string dir); void setsize(unsigned long long backup_size); void setpassword(string pass); + unsigned long long get_size(); public: int use_encryption; @@ -59,6 +60,9 @@ public: int split_archives; int has_data_media; string backup_name; + int progress_pipe_fd; + string partition_name; + string backup_folder; private: int extract(); @@ -75,6 +79,7 @@ private: static void* createList(void *cookie); static void* extractMulti(void *cookie); int tarList(std::vector<TarListStruct> *TarList, unsigned thread_id); + unsigned long long uncompressedSize(string filename, int *archive_type); int Archive_Current_Type; unsigned long long Archive_Current_Size; @@ -84,6 +89,7 @@ private: int fd; pid_t pigz_pid; pid_t oaes_pid; + unsigned long long file_count; string tardir; string tarfn; diff --git a/twrpTarMain/twrpTarMain.cpp b/twrpTarMain/twrpTarMain.cpp index b28a42ea7..c1705c79c 100644 --- a/twrpTarMain/twrpTarMain.cpp +++ b/twrpTarMain/twrpTarMain.cpp @@ -47,6 +47,7 @@ int main(int argc, char **argv) { int i, action = 0; unsigned j; string Directory, Tar_Filename; + unsigned long long temp1 = 0, temp2 = 0; #ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS string Password; #endif @@ -142,14 +143,14 @@ int main(int argc, char **argv) { } #endif if (action == 1) { - if (tar.createTarFork() != 0) { + if (tar.createTarFork(&temp1, &temp2) != 0) { sync(); return -1; } sync(); printf("\n\ntar created successfully.\n"); } else if (action == 2) { - if (tar.extractTarFork() != 0) { + if (tar.extractTarFork(&temp1, &temp2) != 0) { sync(); return -1; } |