blob: 82b24766b485fbb93b25dc9f831a50082b1183ec [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"
bigbiff bigbiff9c754052013-01-09 09:09:08 -050023}
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <string.h>
27#include <errno.h>
28#include <fcntl.h>
29#include <fstream>
bigbiff bigbiff9c754052013-01-09 09:09:08 -050030#include <iostream>
31#include <string>
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -050032#include <sstream>
bigbiff bigbiff9c754052013-01-09 09:09:08 -050033#include <dirent.h>
34#include <sys/mman.h>
35#include "twrpTar.hpp"
36#include "common.h"
37#include "data.hpp"
38#include "variables.h"
bigbiff bigbiff9c754052013-01-09 09:09:08 -050039#include "twrp-functions.hpp"
40
41using namespace std;
42
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -050043void twrpTar::setfn(string fn) {
44 tarfn = fn;
45}
46
47void twrpTar::setdir(string dir) {
48 tardir = dir;
49}
50
51int twrpTar::createTarGZThread() {
52 pthread_t thread;
53 ThreadPtr tarptr = &twrpTar::createTGZ;
54 PThreadPtr p = *(PThreadPtr*)&tarptr;
55 pthread_create(&thread, NULL, p, this);
56 if(pthread_join(thread, NULL)) {
57 return -1;
58 }
59 return 0;
60}
61
62int twrpTar::createTarThread() {
63 pthread_t thread;
64 ThreadPtr tarptr = &twrpTar::create;
65 PThreadPtr p = *(PThreadPtr*)&tarptr;
66 pthread_create(&thread, NULL, p, this);
67 if(pthread_join(thread, NULL)) {
68 return -1;
69 }
70 return 0;
71}
72
73int twrpTar::extractTarThread() {
74 pthread_t thread;
75 ThreadPtr tarptr = &twrpTar::extract;
76 PThreadPtr p = *(PThreadPtr*)&tarptr;
77 pthread_create(&thread, NULL, p, this);
78 if(pthread_join(thread, NULL)) {
79 return -1;
80 }
81 return 0;
82}
83
84int twrpTar::splitArchiveThread() {
85 pthread_t thread;
86 ThreadPtr tarptr = &twrpTar::Split_Archive;
87 PThreadPtr p = *(PThreadPtr*)&tarptr;
88 pthread_create(&thread, NULL, p, this);
89 if(pthread_join(thread, NULL)) {
90 return -1;
91 }
92 return 0;
93}
94
95int twrpTar::Generate_Multiple_Archives(string Path) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -050096 DIR* d;
97 struct dirent* de;
98 struct stat st;
99 string FileName;
100 char actual_filename[255];
101
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500102 if (has_data_media == 1 && Path.size() >= 11 && strncmp(Path.c_str(), "/data/media", 11) == 0)
103 return 0; // Skip /data/media
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500104 LOGI("Path: '%s', archive filename: '%s'\n", Path.c_str(), tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500105
106 d = opendir(Path.c_str());
107 if (d == NULL)
108 {
109 LOGE("error opening '%s' -- error: %s\n", Path.c_str(), strerror(errno));
110 closedir(d);
111 return -1;
112 }
113 while ((de = readdir(d)) != NULL)
114 {
115 FileName = Path + "/";
116 FileName += de->d_name;
117 if (has_data_media == 1 && FileName.size() >= 11 && strncmp(FileName.c_str(), "/data/media", 11) == 0)
118 continue; // Skip /data/media
119 if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
120 {
121 unsigned long long folder_size = TWFunc::Get_Folder_Size(FileName, false);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500122 tardir = FileName;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500123 if (Archive_Current_Size + folder_size > MAX_ARCHIVE_SIZE) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500124 LOGI("Calling Generate_Multiple_Archives\n");
125 if (Generate_Multiple_Archives(FileName) < 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500126 return -1;
127 } else {
128 //FileName += "/";
129 LOGI("Adding folder '%s'\n", FileName.c_str());
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500130 tardir = FileName;
131 if (tarDirs(true) < 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500132 return -1;
133 Archive_Current_Size += folder_size;
134 }
135 }
136 else if (de->d_type == DT_REG || de->d_type == DT_LNK)
137 {
138 stat(FileName.c_str(), &st);
139
140 if (Archive_Current_Size != 0 && Archive_Current_Size + st.st_size > MAX_ARCHIVE_SIZE) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500141 LOGI("Closing tar '%s', ", tarfn.c_str());
142 closeTar(false);
Dees_Troye34c1332013-02-06 19:13:00 +0000143 reinit_libtar_buffer();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500144 if (TWFunc::Get_File_Size(tarfn) == 0) {
145 LOGE("Backup file size for '%s' is 0 bytes.\n", tarfn.c_str());
146 return -1;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500147 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500148 Archive_File_Count++;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500149 if (Archive_File_Count > 999) {
150 LOGE("Archive count is too large!\n");
151 return -1;
152 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500153 string temp = basefn + "%03i";
154 sprintf(actual_filename, temp.c_str(), Archive_File_Count);
155 tarfn = actual_filename;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500156 Archive_Current_Size = 0;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500157 LOGI("Creating tar '%s'\n", tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500158 ui_print("Creating archive %i...\n", Archive_File_Count + 1);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500159 if (createTar() != 0)
160 return -1;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500161 }
162 LOGI("Adding file: '%s'... ", FileName.c_str());
163 if (addFile(FileName, true) < 0)
164 return -1;
165 Archive_Current_Size += st.st_size;
166 LOGI("added successfully, archive size: %llu\n", Archive_Current_Size);
167 if (st.st_size > 2147483648LL)
168 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());
169 }
170 }
171 closedir(d);
172 return 0;
173}
174
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500175int twrpTar::Split_Archive()
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500176{
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500177 string temp = tarfn + "%03i";
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500178 char actual_filename[255];
179
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500180 basefn = tarfn;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500181 Archive_File_Count = 0;
182 Archive_Current_Size = 0;
183 sprintf(actual_filename, temp.c_str(), Archive_File_Count);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500184 tarfn = actual_filename;
Dees_Troye34c1332013-02-06 19:13:00 +0000185 init_libtar_buffer(0);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500186 createTar();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500187 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
188 ui_print("Creating archive 1...\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500189 if (Generate_Multiple_Archives(tardir) < 0) {
Dees_Troye34c1332013-02-06 19:13:00 +0000190 LOGE("Error generating multiple archives\n");
191 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500192 return -1;
193 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500194 closeTar(false);
Dees_Troye34c1332013-02-06 19:13:00 +0000195 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500196 LOGI("Done, created %i archives.\n", (Archive_File_Count++));
197 return (Archive_File_Count);
198}
199
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500200int twrpTar::extractTar() {
Dees_Troye34c1332013-02-06 19:13:00 +0000201 char* charRootDir = (char*) tardir.c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500202 bool gzip = false;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500203 if (openTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500204 return -1;
205 if (tar_extract_all(t, charRootDir) != 0) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500206 LOGE("Unable to extract tar archive '%s'\n", tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500207 return -1;
208 }
209 if (tar_close(t) != 0) {
210 LOGE("Unable to close tar file\n");
211 return -1;
212 }
213 return 0;
214}
215
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500216int twrpTar::extract() {
Dees_Troye34c1332013-02-06 19:13:00 +0000217 int len = 3;
218 char header[len];
219 string::size_type i = 0;
220 int firstbyte = 0;
221 int secondbyte = 0;
222 int ret;
223 ifstream f;
224 f.open(tarfn.c_str(), ios::in | ios::binary);
225 f.get(header, len);
226 firstbyte = header[i] & 0xff;
227 secondbyte = header[++i] & 0xff;
228 f.close();
229 if (firstbyte == 0x1f && secondbyte == 0x8b) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500230 //if you return the extractTGZ function directly, stack crashes happen
231 LOGI("Extracting gzipped tar\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500232 ret = extractTGZ();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500233 return ret;
234 }
235 else {
236 LOGI("Extracting uncompressed tar\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500237 return extractTar();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500238 }
239}
240
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500241int twrpTar::tarDirs(bool include_root) {
Dees_Troye34c1332013-02-06 19:13:00 +0000242 DIR* d;
243 string mainfolder = tardir + "/", subfolder;
244 char buf[1024];
245 char* charTarFile = (char*) tarfn.c_str();
246 d = opendir(tardir.c_str());
247 if (d != NULL) {
248 struct dirent* de;
249 while ((de = readdir(d)) != NULL) {
250 LOGI("adding %s\n", de->d_name);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500251#ifdef RECOVERY_SDCARD_ON_DATA
Dees_Troye34c1332013-02-06 19:13:00 +0000252 if ((tardir == "/data" || tardir == "/data/") && strcmp(de->d_name, "media") == 0) continue;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500253#endif
Dees_Troye34c1332013-02-06 19:13:00 +0000254 if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500255
Dees_Troye34c1332013-02-06 19:13:00 +0000256 subfolder = mainfolder;
257 subfolder += de->d_name;
258 strcpy(buf, subfolder.c_str());
259 if (de->d_type == DT_DIR) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500260 if (include_root) {
Dees_Troye34c1332013-02-06 19:13:00 +0000261 if (tar_append_tree(t, buf, NULL) != 0) {
262 LOGE("Error appending '%s' to tar archive '%s'\n", buf, charTarFile);
263 return -1;
264 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500265 } else {
266 string temp = Strip_Root_Dir(buf);
267 char* charTarPath = (char*) temp.c_str();
268 if (tar_append_tree(t, buf, charTarPath) != 0) {
Dees_Troye34c1332013-02-06 19:13:00 +0000269 LOGE("Error appending '%s' to tar archive '%s'\n", buf, charTarFile);
270 return -1;
271 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500272 }
Dees_Troye34c1332013-02-06 19:13:00 +0000273 } else if (tardir != "/" && (de->d_type == DT_REG || de->d_type == DT_LNK)) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500274 if (addFile(buf, include_root) != 0)
275 return -1;
276 }
Dees_Troye34c1332013-02-06 19:13:00 +0000277 fflush(NULL);
278 }
279 closedir(d);
280 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500281 return 0;
282}
283
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500284int twrpTar::createTGZ() {
Dees_Troye34c1332013-02-06 19:13:00 +0000285 bool gzip = true;
286
287 init_libtar_buffer(0);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500288 if (createTar() == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500289 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500290 if (tarDirs(false) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500291 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500292 if (closeTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500293 return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000294 free_libtar_buffer();
295 return 0;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500296}
297
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500298int twrpTar::create() {
Dees_Troye34c1332013-02-06 19:13:00 +0000299 bool gzip = false;
300
301 init_libtar_buffer(0);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500302 if (createTar() == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500303 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500304 if (tarDirs(false) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500305 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500306 if (closeTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500307 return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000308 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500309 return 0;
310}
311
312int twrpTar::addFilesToExistingTar(vector <string> files, string fn) {
313 char* charTarFile = (char*) fn.c_str();
Dees_Troye34c1332013-02-06 19:13:00 +0000314 static tartype_t type = { open, close, read, write_tar };
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500315
Dees_Troye34c1332013-02-06 19:13:00 +0000316 init_libtar_buffer(0);
317 if (tar_open(&t, charTarFile, &type, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500318 return -1;
319 removeEOT(charTarFile);
Dees_Troye34c1332013-02-06 19:13:00 +0000320 if (tar_open(&t, charTarFile, &type, O_WRONLY | O_APPEND | O_LARGEFILE, 0644, TAR_GNU) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500321 return -1;
322 for (unsigned int i = 0; i < files.size(); ++i) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500323 char* file = (char*) files.at(i).c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500324 if (tar_append_file(t, file, file) == -1)
325 return -1;
326 }
Dees_Troye34c1332013-02-06 19:13:00 +0000327 flush_libtar_buffer(t->fd);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500328 if (tar_append_eof(t) == -1)
329 return -1;
330 if (tar_close(t) == -1)
331 return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000332 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500333 return 0;
334}
335
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500336int twrpTar::createTar() {
337 char* charTarFile = (char*) tarfn.c_str();
Dees_Troye34c1332013-02-06 19:13:00 +0000338 char* charRootDir = (char*) tardir.c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500339 int use_compression = 0;
Dees_Troye34c1332013-02-06 19:13:00 +0000340 static tartype_t type = { open, close, read, write_tar };
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500341
342 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500343 if (use_compression) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500344 string cmd = "pigz - > '" + tarfn + "'";
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500345 p = popen(cmd.c_str(), "w");
346 fd = fileno(p);
347 if (!p) return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000348 if(tar_fdopen(&t, fd, charRootDir, &type, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500349 pclose(p);
350 return -1;
351 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500352 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500353 else {
Dees_Troye34c1332013-02-06 19:13:00 +0000354 if (tar_open(&t, charTarFile, &type, O_WRONLY | O_CREAT | O_LARGEFILE, 0644, TAR_GNU) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500355 return -1;
356 }
357 return 0;
358}
359
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500360int twrpTar::openTar(bool gzip) {
Dees_Troye34c1332013-02-06 19:13:00 +0000361 char* charRootDir = (char*) tardir.c_str();
362 char* charTarFile = (char*) tarfn.c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500363
364 if (gzip) {
365 LOGI("Opening as a gzip\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500366 string cmd = "pigz -d -c '" + tarfn + "'";
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500367 FILE* pipe = popen(cmd.c_str(), "r");
368 int fd = fileno(pipe);
369 if (!pipe) return -1;
370 if(tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
371 LOGI("tar_fdopen returned error\n");
372 pclose(pipe);
373 return -1;
374 }
375 }
376 else {
377 if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
378 LOGE("Unable to open tar archive '%s'\n", charTarFile);
379 return -1;
380 }
381 }
382 return 0;
383}
384
385string twrpTar::Strip_Root_Dir(string Path) {
386 string temp;
387 size_t slash;
388
389 if (Path.substr(0, 1) == "/")
390 temp = Path.substr(1, Path.size() - 1);
391 else
392 temp = Path;
393 slash = temp.find("/");
394 if (slash == string::npos)
395 return temp;
396 else {
397 string stripped;
398
399 stripped = temp.substr(slash, temp.size() - slash);
400 return stripped;
401 }
402 return temp;
403}
404
405int twrpTar::addFile(string fn, bool include_root) {
406 char* charTarFile = (char*) fn.c_str();
407 if (include_root) {
408 if (tar_append_file(t, charTarFile, NULL) == -1)
409 return -1;
410 } else {
411 string temp = Strip_Root_Dir(fn);
412 char* charTarPath = (char*) temp.c_str();
413 if (tar_append_file(t, charTarFile, charTarPath) == -1)
414 return -1;
415 }
416 return 0;
417}
418
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500419int twrpTar::closeTar(bool gzip) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500420 int use_compression;
421 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
422
Dees_Troye34c1332013-02-06 19:13:00 +0000423 flush_libtar_buffer(t->fd);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500424 if (tar_append_eof(t) != 0) {
425 LOGE("tar_append_eof(): %s\n", strerror(errno));
426 tar_close(t);
427 return -1;
428 }
429 if (tar_close(t) != 0) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500430 LOGE("Unable to close tar archive: '%s'\n", tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500431 return -1;
432 }
433 if (use_compression || gzip) {
434 LOGI("Closing popen and fd\n");
435 pclose(p);
436 close(fd);
437 }
438 return 0;
439}
440
441int twrpTar::removeEOT(string tarFile) {
442 char* charTarFile = (char*) tarFile.c_str();
443 off_t tarFileEnd;
444 while (th_read(t) == 0) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500445 if (TH_ISREG(t))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500446 tar_skip_regfile(t);
447 tarFileEnd = lseek(t->fd, 0, SEEK_CUR);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500448 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500449 if (tar_close(t) == -1)
450 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500451 if (truncate(charTarFile, tarFileEnd) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500452 return -1;
453 return 0;
454}
455
456int twrpTar::compress(string fn) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500457 string cmd = "pigz " + fn;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500458 p = popen(cmd.c_str(), "r");
459 if (!p) return -1;
460 char buffer[128];
461 string result = "";
462 while(!feof(p)) {
463 if(fgets(buffer, 128, p) != NULL)
464 result += buffer;
465 }
466 pclose(p);
467 return 0;
468}
469
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500470int twrpTar::extractTGZ() {
471 string splatrootdir(tardir);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500472 bool gzip = true;
Dees_Troye34c1332013-02-06 19:13:00 +0000473 char* splatCharRootDir = (char*) splatrootdir.c_str();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500474 if (openTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500475 return -1;
476 int ret = tar_extract_all(t, splatCharRootDir);
477 if (tar_close(t) != 0) {
478 LOGE("Unable to close tar file\n");
479 return -1;
480 }
Dees_Troye34c1332013-02-06 19:13:00 +0000481 return 0;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500482}
Dees_Troye34c1332013-02-06 19:13:00 +0000483
484extern "C" ssize_t write_tar(int fd, const void *buffer, size_t size) {
485 return (ssize_t) write_libtar_buffer(fd, buffer, size);
486}