blob: 7d46014bdd6318889a3ed01b3a4c35b6fd5e1d8a [file] [log] [blame]
Dees_Troye34c1332013-02-06 19:13:00 +00001/*
2 Copyright 2013 bigbiff/Dees_Troy TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 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.
9
10 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.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17
18 This is a write buffer for use with libtar. Libtar normally writes
19 512 bytes at a time but this results in poor file performance
20 especially on exFAT fuse file systems. This write buffer fixes that
21 problem.
22*/
23
24#include <fcntl.h>
25#include "libtar/libtar.h"
Dees_Troy2673cec2013-04-02 20:22:16 +000026#include "twcommon.h"
Dees_Troye34c1332013-02-06 19:13:00 +000027
28int flush = 0, eot_count = -1;
29unsigned char *write_buffer;
30unsigned buffer_size = 4096;
31unsigned buffer_loc = 0;
Dees_Troy83bd4832013-05-04 12:39:56 +000032int buffer_status = 0;
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
41void init_libtar_buffer(unsigned new_buff_size) {
42 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);
47}
48
49void free_libtar_buffer(void) {
Dees_Troy83bd4832013-05-04 12:39:56 +000050 if (buffer_status > 0)
51 free(write_buffer);
52 buffer_status = 0;
Dees_Troye34c1332013-02-06 19:13:00 +000053}
54
55ssize_t write_libtar_buffer(int fd, const void *buffer, size_t size) {
56 void* ptr;
57
58 if (flush == 0) {
59 ptr = write_buffer + buffer_loc;
60 memcpy(ptr, buffer, size);
61 buffer_loc += size;
62 if (eot_count >= 0 && eot_count < 2)
63 eot_count++;
64 /* At the end of the tar file, libtar will add 2 blank blocks.
65 Once we have received both EOT blocks, we will immediately
66 write anything in the buffer to the file.
67 */
68
69 if (buffer_loc >= buffer_size || eot_count >= 2) {
70 flush = 1;
71 }
72 }
73 if (flush == 1) {
74 flush = 0;
75 if (buffer_loc == 0) {
76 // nothing to write
77 return 0;
78 }
79 if (write(fd, write_buffer, buffer_loc) != buffer_loc) {
Dees_Troy2673cec2013-04-02 20:22:16 +000080 LOGERR("Error writing tar file!\n");
Dees_Troye34c1332013-02-06 19:13:00 +000081 buffer_loc = 0;
82 return -1;
83 } else {
84 buffer_loc = 0;
85 return size;
86 }
87 } else {
88 return size;
89 }
90 // Shouldn't ever get here
91 return -1;
92}
93
94void flush_libtar_buffer(int fd) {
95 eot_count = 0;
Dees_Troy83bd4832013-05-04 12:39:56 +000096 buffer_status = 2;
Dees_Troye34c1332013-02-06 19:13:00 +000097}