blob: 43448672cd9276f2b941edcb3f8d383168b14273 [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 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050060 TWFunc::drop_caches();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -050061 return 0;
62}
63
64int twrpTar::createTarThread() {
65 pthread_t thread;
66 ThreadPtr tarptr = &twrpTar::create;
67 PThreadPtr p = *(PThreadPtr*)&tarptr;
68 pthread_create(&thread, NULL, p, this);
69 if(pthread_join(thread, NULL)) {
70 return -1;
71 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050072 TWFunc::drop_caches();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -050073 return 0;
74}
75
76int twrpTar::extractTarThread() {
77 pthread_t thread;
78 ThreadPtr tarptr = &twrpTar::extract;
79 PThreadPtr p = *(PThreadPtr*)&tarptr;
80 pthread_create(&thread, NULL, p, this);
81 if(pthread_join(thread, NULL)) {
82 return -1;
83 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050084 TWFunc::drop_caches();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -050085 return 0;
86}
87
88int twrpTar::splitArchiveThread() {
89 pthread_t thread;
90 ThreadPtr tarptr = &twrpTar::Split_Archive;
91 PThreadPtr p = *(PThreadPtr*)&tarptr;
92 pthread_create(&thread, NULL, p, this);
93 if(pthread_join(thread, NULL)) {
94 return -1;
95 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050096 TWFunc::drop_caches();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -050097 return 0;
98}
99
100int twrpTar::Generate_Multiple_Archives(string Path) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500101 DIR* d;
102 struct dirent* de;
103 struct stat st;
104 string FileName;
105 char actual_filename[255];
106
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500107 if (has_data_media == 1 && Path.size() >= 11 && strncmp(Path.c_str(), "/data/media", 11) == 0)
108 return 0; // Skip /data/media
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500109 LOGI("Path: '%s', archive filename: '%s'\n", Path.c_str(), tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500110
111 d = opendir(Path.c_str());
112 if (d == NULL)
113 {
114 LOGE("error opening '%s' -- error: %s\n", Path.c_str(), strerror(errno));
115 closedir(d);
116 return -1;
117 }
118 while ((de = readdir(d)) != NULL)
119 {
120 FileName = Path + "/";
121 FileName += de->d_name;
122 if (has_data_media == 1 && FileName.size() >= 11 && strncmp(FileName.c_str(), "/data/media", 11) == 0)
123 continue; // Skip /data/media
124 if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
125 {
126 unsigned long long folder_size = TWFunc::Get_Folder_Size(FileName, false);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500127 tardir = FileName;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500128 if (Archive_Current_Size + folder_size > MAX_ARCHIVE_SIZE) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500129 LOGI("Calling Generate_Multiple_Archives\n");
130 if (Generate_Multiple_Archives(FileName) < 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500131 return -1;
132 } else {
133 //FileName += "/";
134 LOGI("Adding folder '%s'\n", FileName.c_str());
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500135 tardir = FileName;
136 if (tarDirs(true) < 0)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500137 return -1;
138 Archive_Current_Size += folder_size;
139 }
140 }
141 else if (de->d_type == DT_REG || de->d_type == DT_LNK)
142 {
143 stat(FileName.c_str(), &st);
144
145 if (Archive_Current_Size != 0 && Archive_Current_Size + st.st_size > MAX_ARCHIVE_SIZE) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500146 LOGI("Closing tar '%s', ", tarfn.c_str());
147 closeTar(false);
Dees_Troye34c1332013-02-06 19:13:00 +0000148 reinit_libtar_buffer();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500149 if (TWFunc::Get_File_Size(tarfn) == 0) {
150 LOGE("Backup file size for '%s' is 0 bytes.\n", tarfn.c_str());
151 return -1;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500152 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500153 Archive_File_Count++;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500154 if (Archive_File_Count > 999) {
155 LOGE("Archive count is too large!\n");
156 return -1;
157 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500158 string temp = basefn + "%03i";
159 sprintf(actual_filename, temp.c_str(), Archive_File_Count);
160 tarfn = actual_filename;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500161 Archive_Current_Size = 0;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500162 LOGI("Creating tar '%s'\n", tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500163 ui_print("Creating archive %i...\n", Archive_File_Count + 1);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500164 if (createTar() != 0)
165 return -1;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500166 }
167 LOGI("Adding file: '%s'... ", FileName.c_str());
168 if (addFile(FileName, true) < 0)
169 return -1;
170 Archive_Current_Size += st.st_size;
171 LOGI("added successfully, archive size: %llu\n", Archive_Current_Size);
172 if (st.st_size > 2147483648LL)
173 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());
174 }
175 }
176 closedir(d);
177 return 0;
178}
179
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500180int twrpTar::Split_Archive()
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500181{
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500182 string temp = tarfn + "%03i";
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500183 char actual_filename[255];
184
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500185 basefn = tarfn;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500186 Archive_File_Count = 0;
187 Archive_Current_Size = 0;
188 sprintf(actual_filename, temp.c_str(), Archive_File_Count);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500189 tarfn = actual_filename;
Dees_Troye34c1332013-02-06 19:13:00 +0000190 init_libtar_buffer(0);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500191 createTar();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500192 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
193 ui_print("Creating archive 1...\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500194 if (Generate_Multiple_Archives(tardir) < 0) {
Dees_Troye34c1332013-02-06 19:13:00 +0000195 LOGE("Error generating multiple archives\n");
196 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500197 return -1;
198 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500199 closeTar(false);
Dees_Troye34c1332013-02-06 19:13:00 +0000200 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500201 LOGI("Done, created %i archives.\n", (Archive_File_Count++));
202 return (Archive_File_Count);
203}
204
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500205int twrpTar::extractTar() {
Dees_Troye34c1332013-02-06 19:13:00 +0000206 char* charRootDir = (char*) tardir.c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500207 bool gzip = false;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500208 if (openTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500209 return -1;
210 if (tar_extract_all(t, charRootDir) != 0) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500211 LOGE("Unable to extract tar archive '%s'\n", tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500212 return -1;
213 }
214 if (tar_close(t) != 0) {
215 LOGE("Unable to close tar file\n");
216 return -1;
217 }
218 return 0;
219}
220
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500221int twrpTar::extract() {
Dees_Troye34c1332013-02-06 19:13:00 +0000222 int len = 3;
223 char header[len];
224 string::size_type i = 0;
225 int firstbyte = 0;
226 int secondbyte = 0;
227 int ret;
228 ifstream f;
229 f.open(tarfn.c_str(), ios::in | ios::binary);
230 f.get(header, len);
231 firstbyte = header[i] & 0xff;
232 secondbyte = header[++i] & 0xff;
233 f.close();
234 if (firstbyte == 0x1f && secondbyte == 0x8b) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500235 //if you return the extractTGZ function directly, stack crashes happen
236 LOGI("Extracting gzipped tar\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500237 ret = extractTGZ();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500238 return ret;
239 }
240 else {
241 LOGI("Extracting uncompressed tar\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500242 return extractTar();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500243 }
244}
245
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500246int twrpTar::tarDirs(bool include_root) {
Dees_Troye34c1332013-02-06 19:13:00 +0000247 DIR* d;
248 string mainfolder = tardir + "/", subfolder;
249 char buf[1024];
250 char* charTarFile = (char*) tarfn.c_str();
251 d = opendir(tardir.c_str());
252 if (d != NULL) {
253 struct dirent* de;
254 while ((de = readdir(d)) != NULL) {
255 LOGI("adding %s\n", de->d_name);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500256#ifdef RECOVERY_SDCARD_ON_DATA
Dees_Troye34c1332013-02-06 19:13:00 +0000257 if ((tardir == "/data" || tardir == "/data/") && strcmp(de->d_name, "media") == 0) continue;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500258#endif
Dees_Troye34c1332013-02-06 19:13:00 +0000259 if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500260
Dees_Troye34c1332013-02-06 19:13:00 +0000261 subfolder = mainfolder;
262 subfolder += de->d_name;
263 strcpy(buf, subfolder.c_str());
264 if (de->d_type == DT_DIR) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500265 if (include_root) {
Dees_Troye34c1332013-02-06 19:13:00 +0000266 if (tar_append_tree(t, buf, NULL) != 0) {
267 LOGE("Error appending '%s' to tar archive '%s'\n", buf, charTarFile);
268 return -1;
269 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500270 } else {
271 string temp = Strip_Root_Dir(buf);
272 char* charTarPath = (char*) temp.c_str();
273 if (tar_append_tree(t, buf, charTarPath) != 0) {
Dees_Troye34c1332013-02-06 19:13:00 +0000274 LOGE("Error appending '%s' to tar archive '%s'\n", buf, charTarFile);
275 return -1;
276 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500277 }
Dees_Troye34c1332013-02-06 19:13:00 +0000278 } else if (tardir != "/" && (de->d_type == DT_REG || de->d_type == DT_LNK)) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500279 if (addFile(buf, include_root) != 0)
280 return -1;
281 }
Dees_Troye34c1332013-02-06 19:13:00 +0000282 fflush(NULL);
283 }
284 closedir(d);
285 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500286 return 0;
287}
288
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500289int twrpTar::createTGZ() {
Dees_Troye34c1332013-02-06 19:13:00 +0000290 bool gzip = true;
291
292 init_libtar_buffer(0);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500293 if (createTar() == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500294 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500295 if (tarDirs(false) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500296 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500297 if (closeTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500298 return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000299 free_libtar_buffer();
300 return 0;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500301}
302
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500303int twrpTar::create() {
Dees_Troye34c1332013-02-06 19:13:00 +0000304 bool gzip = false;
305
306 init_libtar_buffer(0);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500307 if (createTar() == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500308 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500309 if (tarDirs(false) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500310 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500311 if (closeTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500312 return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000313 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500314 return 0;
315}
316
317int twrpTar::addFilesToExistingTar(vector <string> files, string fn) {
318 char* charTarFile = (char*) fn.c_str();
Dees_Troye34c1332013-02-06 19:13:00 +0000319 static tartype_t type = { open, close, read, write_tar };
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500320
Dees_Troye34c1332013-02-06 19:13:00 +0000321 init_libtar_buffer(0);
322 if (tar_open(&t, charTarFile, &type, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500323 return -1;
324 removeEOT(charTarFile);
Dees_Troye34c1332013-02-06 19:13:00 +0000325 if (tar_open(&t, charTarFile, &type, O_WRONLY | O_APPEND | O_LARGEFILE, 0644, TAR_GNU) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500326 return -1;
327 for (unsigned int i = 0; i < files.size(); ++i) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500328 char* file = (char*) files.at(i).c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500329 if (tar_append_file(t, file, file) == -1)
330 return -1;
331 }
Dees_Troye34c1332013-02-06 19:13:00 +0000332 flush_libtar_buffer(t->fd);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500333 if (tar_append_eof(t) == -1)
334 return -1;
335 if (tar_close(t) == -1)
336 return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000337 free_libtar_buffer();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500338 return 0;
339}
340
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500341int twrpTar::createTar() {
342 char* charTarFile = (char*) tarfn.c_str();
Dees_Troye34c1332013-02-06 19:13:00 +0000343 char* charRootDir = (char*) tardir.c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500344 int use_compression = 0;
Dees_Troye34c1332013-02-06 19:13:00 +0000345 static tartype_t type = { open, close, read, write_tar };
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500346
347 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500348 if (use_compression) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500349 string cmd = "pigz - > '" + tarfn + "'";
Dees_Troy40bbcf82013-02-12 15:01:53 +0000350 p = __popen(cmd.c_str(), "w");
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500351 fd = fileno(p);
352 if (!p) return -1;
Dees_Troye34c1332013-02-06 19:13:00 +0000353 if(tar_fdopen(&t, fd, charRootDir, &type, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500354 pclose(p);
355 return -1;
356 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500357 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500358 else {
Dees_Troye34c1332013-02-06 19:13:00 +0000359 if (tar_open(&t, charTarFile, &type, O_WRONLY | O_CREAT | O_LARGEFILE, 0644, TAR_GNU) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500360 return -1;
361 }
362 return 0;
363}
364
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500365int twrpTar::openTar(bool gzip) {
Dees_Troye34c1332013-02-06 19:13:00 +0000366 char* charRootDir = (char*) tardir.c_str();
367 char* charTarFile = (char*) tarfn.c_str();
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500368
369 if (gzip) {
370 LOGI("Opening as a gzip\n");
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500371 string cmd = "pigz -d -c '" + tarfn + "'";
Dees_Troy40bbcf82013-02-12 15:01:53 +0000372 FILE* pipe = __popen(cmd.c_str(), "r");
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500373 int fd = fileno(pipe);
374 if (!pipe) return -1;
375 if(tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
376 LOGI("tar_fdopen returned error\n");
Dees_Troy40bbcf82013-02-12 15:01:53 +0000377 __pclose(pipe);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500378 return -1;
379 }
380 }
381 else {
382 if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
383 LOGE("Unable to open tar archive '%s'\n", charTarFile);
384 return -1;
385 }
386 }
387 return 0;
388}
389
390string twrpTar::Strip_Root_Dir(string Path) {
391 string temp;
392 size_t slash;
393
394 if (Path.substr(0, 1) == "/")
395 temp = Path.substr(1, Path.size() - 1);
396 else
397 temp = Path;
398 slash = temp.find("/");
399 if (slash == string::npos)
400 return temp;
401 else {
402 string stripped;
403
404 stripped = temp.substr(slash, temp.size() - slash);
405 return stripped;
406 }
407 return temp;
408}
409
410int twrpTar::addFile(string fn, bool include_root) {
411 char* charTarFile = (char*) fn.c_str();
412 if (include_root) {
413 if (tar_append_file(t, charTarFile, NULL) == -1)
414 return -1;
415 } else {
416 string temp = Strip_Root_Dir(fn);
417 char* charTarPath = (char*) temp.c_str();
418 if (tar_append_file(t, charTarFile, charTarPath) == -1)
419 return -1;
420 }
421 return 0;
422}
423
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500424int twrpTar::closeTar(bool gzip) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500425 int use_compression;
426 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
427
Dees_Troye34c1332013-02-06 19:13:00 +0000428 flush_libtar_buffer(t->fd);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500429 if (tar_append_eof(t) != 0) {
430 LOGE("tar_append_eof(): %s\n", strerror(errno));
431 tar_close(t);
432 return -1;
433 }
434 if (tar_close(t) != 0) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500435 LOGE("Unable to close tar archive: '%s'\n", tarfn.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500436 return -1;
437 }
438 if (use_compression || gzip) {
439 LOGI("Closing popen and fd\n");
440 pclose(p);
441 close(fd);
442 }
443 return 0;
444}
445
446int twrpTar::removeEOT(string tarFile) {
447 char* charTarFile = (char*) tarFile.c_str();
448 off_t tarFileEnd;
449 while (th_read(t) == 0) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500450 if (TH_ISREG(t))
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500451 tar_skip_regfile(t);
452 tarFileEnd = lseek(t->fd, 0, SEEK_CUR);
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500453 }
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500454 if (tar_close(t) == -1)
455 return -1;
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500456 if (truncate(charTarFile, tarFileEnd) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500457 return -1;
458 return 0;
459}
460
461int twrpTar::compress(string fn) {
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500462 string cmd = "pigz " + fn;
Dees_Troy40bbcf82013-02-12 15:01:53 +0000463 p = __popen(cmd.c_str(), "r");
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500464 if (!p) return -1;
465 char buffer[128];
466 string result = "";
467 while(!feof(p)) {
468 if(fgets(buffer, 128, p) != NULL)
469 result += buffer;
470 }
Dees_Troy40bbcf82013-02-12 15:01:53 +0000471 __pclose(p);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500472 return 0;
473}
474
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500475int twrpTar::extractTGZ() {
476 string splatrootdir(tardir);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500477 bool gzip = true;
Dees_Troye34c1332013-02-06 19:13:00 +0000478 char* splatCharRootDir = (char*) splatrootdir.c_str();
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500479 if (openTar(gzip) == -1)
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500480 return -1;
481 int ret = tar_extract_all(t, splatCharRootDir);
482 if (tar_close(t) != 0) {
483 LOGE("Unable to close tar file\n");
484 return -1;
485 }
Dees_Troye34c1332013-02-06 19:13:00 +0000486 return 0;
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500487}
Dees_Troye34c1332013-02-06 19:13:00 +0000488
489extern "C" ssize_t write_tar(int fd, const void *buffer, size_t size) {
490 return (ssize_t) write_libtar_buffer(fd, buffer, size);
Dees_Troy40bbcf82013-02-12 15:01:53 +0000491}