blob: 26368499505c43f0579c546c1ad6cc0e083a4b4b [file] [log] [blame]
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001/*
Dees_Troye34c1332013-02-06 19:13:00 +00002 Copyright 2012 bigbiff/Dees_Troy TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
bigbiff bigbiff9c754052013-01-09 09:09:08 -05004
Dees_Troye34c1332013-02-06 19:13:00 +00005 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
bigbiff bigbiff9c754052013-01-09 09:09:08 -05009
Dees_Troye34c1332013-02-06 19:13:00 +000010 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
bigbiff bigbiff9c754052013-01-09 09:09:08 -050014
Dees_Troye34c1332013-02-06 19:13:00 +000015 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
bigbiff bigbiff9c754052013-01-09 09:09:08 -050017*/
18
19extern "C" {
20 #include "libtar/libtar.h"
Dees_Troye34c1332013-02-06 19:13:00 +000021 #include "twrpTar.h"
22 #include "tarWrite.h"
Dees_Troy40bbcf82013-02-12 15:01:53 +000023 #include "libcrecovery/common.h"
bigbiff bigbiff9c754052013-01-09 09:09:08 -050024}
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <string.h>
28#include <errno.h>
29#include <fcntl.h>
30#include <fstream>
bigbiff bigbiff9c754052013-01-09 09:09:08 -050031#include <iostream>
32#include <string>
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -050033#include <sstream>
bigbiff bigbiff9c754052013-01-09 09:09:08 -050034#include <dirent.h>
35#include <sys/mman.h>
36#include "twrpTar.hpp"
37#include "common.h"
38#include "data.hpp"
39#include "variables.h"
bigbiff bigbiff9c754052013-01-09 09:09:08 -050040#include "twrp-functions.hpp"
41
42using namespace std;
43
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -050044void twrpTar::setfn(string fn) {
45 tarfn = fn;
46}
47
48void twrpTar::setdir(string dir) {
49 tardir = dir;
50}
51
52int twrpTar::createTarGZThread() {
53 pthread_t thread;
54 ThreadPtr tarptr = &twrpTar::createTGZ;
55 PThreadPtr p = *(PThreadPtr*)&tarptr;
56 pthread_create(&thread, NULL, p, this);
57 if(pthread_join(thread, NULL)) {
58 return -1;
59 }
60 return 0;
61}
62
63int twrpTar::createTarThread() {
64 pthread_t thread;
65 ThreadPtr tarptr = &twrpTar::create;
66 PThreadPtr p = *(PThreadPtr*)&tarptr;
67 pthread_create(&thread, NULL, p, this);
68 if(pthread_join(thread, NULL)) {
69 return -1;
70 }
71 return 0;
72}
73
74int twrpTar::extractTarThread() {
75 pthread_t thread;
76 ThreadPtr tarptr = &twrpTar::extract;
77 PThreadPtr p = *(PThreadPtr*)&tarptr;
78 pthread_create(&thread, NULL, p, this);
79 if(pthread_join(thread, NULL)) {
80 return -1;
81 }
82 return 0;
83}
84
85int twrpTar::splitArchiveThread() {
86 pthread_t thread;
87 ThreadPtr tarptr = &twrpTar::Split_Archive;
88 PThreadPtr p = *(PThreadPtr*)&tarptr;
89 pthread_create(&thread, NULL, p, this);
90 if(pthread_join(thread, NULL)) {
91 return -1;
92 }
93 return 0;
94}
95
96int twrpTar::Generate_Multiple_Archives(string Path) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -050097 DIR* d;
98 struct dirent* de;
99 struct stat st;
100 string FileName;
101 char actual_filename[255];
102
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500103 if (has_data_media == 1 && Path.size() >= 11 && strncmp(Path.c_str(), "/data/media", 11) == 0)
104 return 0; // Skip /data/media
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500105 LOGI("Path: '%s', archive filename: '%s'\n", Path.c_str(), tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500106
107 d = opendir(Path.c_str());
108 if (d == NULL)
109 {
110 LOGE("error opening '%s' -- error: %s\n", Path.c_str(), strerror(errno));
111 closedir(d);
112 return -1;
113 }
114 while ((de = readdir(d)) != NULL)
115 {
116 FileName = Path + "/";
117 FileName += de->d_name;
118 if (has_data_media == 1 && FileName.size() >= 11 && strncmp(FileName.c_str(), "/data/media", 11) == 0)
119 continue; // Skip /data/media
120 if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
121 {
122 unsigned long long folder_size = TWFunc::Get_Folder_Size(FileName, false);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500123 tardir = FileName;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500124 if (Archive_Current_Size + folder_size > MAX_ARCHIVE_SIZE) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500125 LOGI("Calling Generate_Multiple_Archives\n");
126 if (Generate_Multiple_Archives(FileName) < 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500127 return -1;
128 } else {
129 //FileName += "/";
130 LOGI("Adding folder '%s'\n", FileName.c_str());
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500131 tardir = FileName;
132 if (tarDirs(true) < 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500133 return -1;
134 Archive_Current_Size += folder_size;
135 }
136 }
137 else if (de->d_type == DT_REG || de->d_type == DT_LNK)
138 {
139 stat(FileName.c_str(), &st);
140
141 if (Archive_Current_Size != 0 && Archive_Current_Size + st.st_size > MAX_ARCHIVE_SIZE) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500142 LOGI("Closing tar '%s', ", tarfn.c_str());
143 closeTar(false);
Dees_Troye34c1332013-02-06 19:13:00 +0000144 reinit_libtar_buffer();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500145 if (TWFunc::Get_File_Size(tarfn) == 0) {
146 LOGE("Backup file size for '%s' is 0 bytes.\n", tarfn.c_str());
147 return -1;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500148 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500149 Archive_File_Count++;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500150 if (Archive_File_Count > 999) {
151 LOGE("Archive count is too large!\n");
152 return -1;
153 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500154 string temp = basefn + "%03i";
155 sprintf(actual_filename, temp.c_str(), Archive_File_Count);
156 tarfn = actual_filename;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500157 Archive_Current_Size = 0;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500158 LOGI("Creating tar '%s'\n", tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500159 ui_print("Creating archive %i...\n", Archive_File_Count + 1);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500160 if (createTar() != 0)
161 return -1;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500162 }
163 LOGI("Adding file: '%s'... ", FileName.c_str());
164 if (addFile(FileName, true) < 0)
165 return -1;
166 Archive_Current_Size += st.st_size;
167 LOGI("added successfully, archive size: %llu\n", Archive_Current_Size);
168 if (st.st_size > 2147483648LL)
169 LOGE("There is a file that is larger than 2GB in the file system\n'%s'\nThis file may not restore properly\n", FileName.c_str());
170 }
171 }
172 closedir(d);
173 return 0;
174}
175
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500176int twrpTar::Split_Archive()
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500177{
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500178 string temp = tarfn + "%03i";
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500179 char actual_filename[255];
180
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500181 basefn = tarfn;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500182 Archive_File_Count = 0;
183 Archive_Current_Size = 0;
184 sprintf(actual_filename, temp.c_str(), Archive_File_Count);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500185 tarfn = actual_filename;
Dees_Troye34c1332013-02-06 19:13:00 +0000186 init_libtar_buffer(0);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500187 createTar();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500188 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
189 ui_print("Creating archive 1...\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500190 if (Generate_Multiple_Archives(tardir) < 0) {
Dees_Troye34c1332013-02-06 19:13:00 +0000191 LOGE("Error generating multiple archives\n");
192 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500193 return -1;
194 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500195 closeTar(false);
Dees_Troye34c1332013-02-06 19:13:00 +0000196 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500197 LOGI("Done, created %i archives.\n", (Archive_File_Count++));
198 return (Archive_File_Count);
199}
200
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500201int twrpTar::extractTar() {
Dees_Troye34c1332013-02-06 19:13:00 +0000202 char* charRootDir = (char*) tardir.c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500203 bool gzip = false;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500204 if (openTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500205 return -1;
206 if (tar_extract_all(t, charRootDir) != 0) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500207 LOGE("Unable to extract tar archive '%s'\n", tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500208 return -1;
209 }
210 if (tar_close(t) != 0) {
211 LOGE("Unable to close tar file\n");
212 return -1;
213 }
214 return 0;
215}
216
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500217int twrpTar::extract() {
Dees_Troye34c1332013-02-06 19:13:00 +0000218 int len = 3;
219 char header[len];
220 string::size_type i = 0;
221 int firstbyte = 0;
222 int secondbyte = 0;
223 int ret;
224 ifstream f;
225 f.open(tarfn.c_str(), ios::in | ios::binary);
226 f.get(header, len);
227 firstbyte = header[i] & 0xff;
228 secondbyte = header[++i] & 0xff;
229 f.close();
230 if (firstbyte == 0x1f && secondbyte == 0x8b) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500231 //if you return the extractTGZ function directly, stack crashes happen
232 LOGI("Extracting gzipped tar\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500233 ret = extractTGZ();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500234 return ret;
235 }
236 else {
237 LOGI("Extracting uncompressed tar\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500238 return extractTar();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500239 }
240}
241
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500242int twrpTar::tarDirs(bool include_root) {
Dees_Troye34c1332013-02-06 19:13:00 +0000243 DIR* d;
244 string mainfolder = tardir + "/", subfolder;
245 char buf[1024];
246 char* charTarFile = (char*) tarfn.c_str();
247 d = opendir(tardir.c_str());
248 if (d != NULL) {
249 struct dirent* de;
250 while ((de = readdir(d)) != NULL) {
251 LOGI("adding %s\n", de->d_name);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500252#ifdef RECOVERY_SDCARD_ON_DATA
Dees_Troye34c1332013-02-06 19:13:00 +0000253 if ((tardir == "/data" || tardir == "/data/") && strcmp(de->d_name, "media") == 0) continue;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500254#endif
Dees_Troye34c1332013-02-06 19:13:00 +0000255 if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500256
Dees_Troye34c1332013-02-06 19:13:00 +0000257 subfolder = mainfolder;
258 subfolder += de->d_name;
259 strcpy(buf, subfolder.c_str());
260 if (de->d_type == DT_DIR) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500261 if (include_root) {
Dees_Troye34c1332013-02-06 19:13:00 +0000262 if (tar_append_tree(t, buf, NULL) != 0) {
263 LOGE("Error appending '%s' to tar archive '%s'\n", buf, charTarFile);
264 return -1;
265 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500266 } else {
267 string temp = Strip_Root_Dir(buf);
268 char* charTarPath = (char*) temp.c_str();
269 if (tar_append_tree(t, buf, charTarPath) != 0) {
Dees_Troye34c1332013-02-06 19:13:00 +0000270 LOGE("Error appending '%s' to tar archive '%s'\n", buf, charTarFile);
271 return -1;
272 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500273 }
Dees_Troye34c1332013-02-06 19:13:00 +0000274 } else if (tardir != "/" && (de->d_type == DT_REG || de->d_type == DT_LNK)) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500275 if (addFile(buf, include_root) != 0)
276 return -1;
277 }
Dees_Troye34c1332013-02-06 19:13:00 +0000278 fflush(NULL);
279 }
280 closedir(d);
281 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500282 return 0;
283}
284
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500285int twrpTar::createTGZ() {
Dees_Troye34c1332013-02-06 19:13:00 +0000286 bool gzip = true;
287
288 init_libtar_buffer(0);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500289 if (createTar() == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500290 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500291 if (tarDirs(false) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500292 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500293 if (closeTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500294 return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000295 free_libtar_buffer();
296 return 0;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500297}
298
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500299int twrpTar::create() {
Dees_Troye34c1332013-02-06 19:13:00 +0000300 bool gzip = false;
301
302 init_libtar_buffer(0);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500303 if (createTar() == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500304 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500305 if (tarDirs(false) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500306 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500307 if (closeTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500308 return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000309 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500310 return 0;
311}
312
313int twrpTar::addFilesToExistingTar(vector <string> files, string fn) {
314 char* charTarFile = (char*) fn.c_str();
Dees_Troye34c1332013-02-06 19:13:00 +0000315 static tartype_t type = { open, close, read, write_tar };
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500316
Dees_Troye34c1332013-02-06 19:13:00 +0000317 init_libtar_buffer(0);
318 if (tar_open(&t, charTarFile, &type, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500319 return -1;
320 removeEOT(charTarFile);
Dees_Troye34c1332013-02-06 19:13:00 +0000321 if (tar_open(&t, charTarFile, &type, O_WRONLY | O_APPEND | O_LARGEFILE, 0644, TAR_GNU) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500322 return -1;
323 for (unsigned int i = 0; i < files.size(); ++i) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500324 char* file = (char*) files.at(i).c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500325 if (tar_append_file(t, file, file) == -1)
326 return -1;
327 }
Dees_Troye34c1332013-02-06 19:13:00 +0000328 flush_libtar_buffer(t->fd);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500329 if (tar_append_eof(t) == -1)
330 return -1;
331 if (tar_close(t) == -1)
332 return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000333 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500334 return 0;
335}
336
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500337int twrpTar::createTar() {
338 char* charTarFile = (char*) tarfn.c_str();
Dees_Troye34c1332013-02-06 19:13:00 +0000339 char* charRootDir = (char*) tardir.c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500340 int use_compression = 0;
Dees_Troye34c1332013-02-06 19:13:00 +0000341 static tartype_t type = { open, close, read, write_tar };
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500342
343 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500344 if (use_compression) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500345 string cmd = "pigz - > '" + tarfn + "'";
Dees_Troy40bbcf82013-02-12 15:01:53 +0000346 p = __popen(cmd.c_str(), "w");
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500347 fd = fileno(p);
348 if (!p) return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000349 if(tar_fdopen(&t, fd, charRootDir, &type, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500350 pclose(p);
351 return -1;
352 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500353 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500354 else {
Dees_Troye34c1332013-02-06 19:13:00 +0000355 if (tar_open(&t, charTarFile, &type, O_WRONLY | O_CREAT | O_LARGEFILE, 0644, TAR_GNU) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500356 return -1;
357 }
358 return 0;
359}
360
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500361int twrpTar::openTar(bool gzip) {
Dees_Troye34c1332013-02-06 19:13:00 +0000362 char* charRootDir = (char*) tardir.c_str();
363 char* charTarFile = (char*) tarfn.c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500364
365 if (gzip) {
366 LOGI("Opening as a gzip\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500367 string cmd = "pigz -d -c '" + tarfn + "'";
Dees_Troy40bbcf82013-02-12 15:01:53 +0000368 FILE* pipe = __popen(cmd.c_str(), "r");
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500369 int fd = fileno(pipe);
370 if (!pipe) return -1;
371 if(tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
372 LOGI("tar_fdopen returned error\n");
Dees_Troy40bbcf82013-02-12 15:01:53 +0000373 __pclose(pipe);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500374 return -1;
375 }
376 }
377 else {
378 if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
379 LOGE("Unable to open tar archive '%s'\n", charTarFile);
380 return -1;
381 }
382 }
383 return 0;
384}
385
386string twrpTar::Strip_Root_Dir(string Path) {
387 string temp;
388 size_t slash;
389
390 if (Path.substr(0, 1) == "/")
391 temp = Path.substr(1, Path.size() - 1);
392 else
393 temp = Path;
394 slash = temp.find("/");
395 if (slash == string::npos)
396 return temp;
397 else {
398 string stripped;
399
400 stripped = temp.substr(slash, temp.size() - slash);
401 return stripped;
402 }
403 return temp;
404}
405
406int twrpTar::addFile(string fn, bool include_root) {
407 char* charTarFile = (char*) fn.c_str();
408 if (include_root) {
409 if (tar_append_file(t, charTarFile, NULL) == -1)
410 return -1;
411 } else {
412 string temp = Strip_Root_Dir(fn);
413 char* charTarPath = (char*) temp.c_str();
414 if (tar_append_file(t, charTarFile, charTarPath) == -1)
415 return -1;
416 }
417 return 0;
418}
419
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500420int twrpTar::closeTar(bool gzip) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500421 int use_compression;
422 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
423
Dees_Troye34c1332013-02-06 19:13:00 +0000424 flush_libtar_buffer(t->fd);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500425 if (tar_append_eof(t) != 0) {
426 LOGE("tar_append_eof(): %s\n", strerror(errno));
427 tar_close(t);
428 return -1;
429 }
430 if (tar_close(t) != 0) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500431 LOGE("Unable to close tar archive: '%s'\n", tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500432 return -1;
433 }
434 if (use_compression || gzip) {
435 LOGI("Closing popen and fd\n");
436 pclose(p);
437 close(fd);
438 }
439 return 0;
440}
441
442int twrpTar::removeEOT(string tarFile) {
443 char* charTarFile = (char*) tarFile.c_str();
444 off_t tarFileEnd;
445 while (th_read(t) == 0) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500446 if (TH_ISREG(t))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500447 tar_skip_regfile(t);
448 tarFileEnd = lseek(t->fd, 0, SEEK_CUR);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500449 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500450 if (tar_close(t) == -1)
451 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500452 if (truncate(charTarFile, tarFileEnd) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500453 return -1;
454 return 0;
455}
456
457int twrpTar::compress(string fn) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500458 string cmd = "pigz " + fn;
Dees_Troy40bbcf82013-02-12 15:01:53 +0000459 p = __popen(cmd.c_str(), "r");
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500460 if (!p) return -1;
461 char buffer[128];
462 string result = "";
463 while(!feof(p)) {
464 if(fgets(buffer, 128, p) != NULL)
465 result += buffer;
466 }
Dees_Troy40bbcf82013-02-12 15:01:53 +0000467 __pclose(p);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500468 return 0;
469}
470
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500471int twrpTar::extractTGZ() {
472 string splatrootdir(tardir);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500473 bool gzip = true;
Dees_Troye34c1332013-02-06 19:13:00 +0000474 char* splatCharRootDir = (char*) splatrootdir.c_str();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500475 if (openTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500476 return -1;
477 int ret = tar_extract_all(t, splatCharRootDir);
478 if (tar_close(t) != 0) {
479 LOGE("Unable to close tar file\n");
480 return -1;
481 }
Dees_Troye34c1332013-02-06 19:13:00 +0000482 return 0;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500483}
Dees_Troye34c1332013-02-06 19:13:00 +0000484
485extern "C" ssize_t write_tar(int fd, const void *buffer, size_t size) {
486 return (ssize_t) write_libtar_buffer(fd, buffer, size);
Dees_Troy40bbcf82013-02-12 15:01:53 +0000487}