blob: 98461452a42ff0e28d4fa22c3fba065683d59994 [file] [log] [blame]
Dees_Troye34c1332013-02-06 19:13:00 +00001/*
Dees Troy3be70a82013-10-22 14:25:12 +00002 Copyright 2012 bigbiff/Dees_Troy TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
Dees_Troye34c1332013-02-06 19:13:00 +00004
Dees Troy3be70a82013-10-22 14:25:12 +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.
Dees_Troye34c1332013-02-06 19:13:00 +00009
Dees Troy3be70a82013-10-22 14:25:12 +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.
Dees_Troye34c1332013-02-06 19:13:00 +000014
Dees Troy3be70a82013-10-22 14:25:12 +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/>.
Dees_Troye34c1332013-02-06 19:13:00 +000017*/
18
19#include <fcntl.h>
Ethan Yonkerc798c9c2015-10-09 11:15:26 -050020#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
Dees_Troye34c1332013-02-06 19:13:00 +000023#include "libtar/libtar.h"
Dees_Troy2673cec2013-04-02 20:22:16 +000024#include "twcommon.h"
Dees_Troye34c1332013-02-06 19:13:00 +000025
26int flush = 0, eot_count = -1;
27unsigned char *write_buffer;
28unsigned buffer_size = 4096;
29unsigned buffer_loc = 0;
Dees_Troy83bd4832013-05-04 12:39:56 +000030int buffer_status = 0;
Ethan Yonker472f5062016-02-25 13:47:30 -060031int prog_pipe = -1;
32const unsigned long long progress_size = (unsigned long long)(T_BLOCKSIZE);
Dees_Troye34c1332013-02-06 19:13:00 +000033
34void reinit_libtar_buffer(void) {
35 flush = 0;
36 eot_count = -1;
37 buffer_loc = 0;
Dees_Troy83bd4832013-05-04 12:39:56 +000038 buffer_status = 1;
Dees_Troye34c1332013-02-06 19:13:00 +000039}
40
Ethan Yonker472f5062016-02-25 13:47:30 -060041void init_libtar_buffer(unsigned new_buff_size, int pipe_fd) {
Dees_Troye34c1332013-02-06 19:13:00 +000042 if (new_buff_size != 0)
43 buffer_size = new_buff_size;
44
45 reinit_libtar_buffer();
46 write_buffer = (unsigned char*) malloc(sizeof(char *) * buffer_size);
Ethan Yonker472f5062016-02-25 13:47:30 -060047 prog_pipe = pipe_fd;
Dees_Troye34c1332013-02-06 19:13:00 +000048}
49
50void free_libtar_buffer(void) {
Dees_Troy83bd4832013-05-04 12:39:56 +000051 if (buffer_status > 0)
52 free(write_buffer);
53 buffer_status = 0;
Ethan Yonker472f5062016-02-25 13:47:30 -060054 prog_pipe = -1;
Dees_Troye34c1332013-02-06 19:13:00 +000055}
56
57ssize_t write_libtar_buffer(int fd, const void *buffer, size_t size) {
58 void* ptr;
59
60 if (flush == 0) {
61 ptr = write_buffer + buffer_loc;
62 memcpy(ptr, buffer, size);
63 buffer_loc += size;
64 if (eot_count >= 0 && eot_count < 2)
65 eot_count++;
66 /* At the end of the tar file, libtar will add 2 blank blocks.
67 Once we have received both EOT blocks, we will immediately
68 write anything in the buffer to the file.
69 */
70
71 if (buffer_loc >= buffer_size || eot_count >= 2) {
72 flush = 1;
73 }
74 }
75 if (flush == 1) {
76 flush = 0;
77 if (buffer_loc == 0) {
78 // nothing to write
79 return 0;
80 }
Ethan Yonkerc798c9c2015-10-09 11:15:26 -050081 if (write(fd, write_buffer, buffer_loc) != (int)buffer_loc) {
Dees_Troy2673cec2013-04-02 20:22:16 +000082 LOGERR("Error writing tar file!\n");
Dees_Troye34c1332013-02-06 19:13:00 +000083 buffer_loc = 0;
84 return -1;
85 } else {
Ethan Yonker472f5062016-02-25 13:47:30 -060086 unsigned long long fs = (unsigned long long)(buffer_loc);
87 write(prog_pipe, &fs, sizeof(fs));
Dees_Troye34c1332013-02-06 19:13:00 +000088 buffer_loc = 0;
89 return size;
90 }
91 } else {
92 return size;
93 }
94 // Shouldn't ever get here
95 return -1;
96}
97
98void flush_libtar_buffer(int fd) {
99 eot_count = 0;
Ethan Yonker74db84e2015-06-01 09:55:00 -0500100 if (buffer_status)
101 buffer_status = 2;
Dees_Troye34c1332013-02-06 19:13:00 +0000102}
Ethan Yonker472f5062016-02-25 13:47:30 -0600103
104void init_libtar_no_buffer(int pipe_fd) {
105 buffer_size = T_BLOCKSIZE;
106 prog_pipe = pipe_fd;
107 buffer_status = 0;
108}
109
110ssize_t write_libtar_no_buffer(int fd, const void *buffer, size_t size) {
111 write(prog_pipe, &progress_size, sizeof(progress_size));
112 return write(fd, buffer, size);
113}