blob: f5af4491ba65ba0c9bf41fdd59eb7a92d6b8c99c [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;
32
33void reinit_libtar_buffer(void) {
34 flush = 0;
35 eot_count = -1;
36 buffer_loc = 0;
37}
38
39void init_libtar_buffer(unsigned new_buff_size) {
40 if (new_buff_size != 0)
41 buffer_size = new_buff_size;
42
43 reinit_libtar_buffer();
44 write_buffer = (unsigned char*) malloc(sizeof(char *) * buffer_size);
45}
46
47void free_libtar_buffer(void) {
48 free(write_buffer);
49}
50
51ssize_t write_libtar_buffer(int fd, const void *buffer, size_t size) {
52 void* ptr;
53
54 if (flush == 0) {
55 ptr = write_buffer + buffer_loc;
56 memcpy(ptr, buffer, size);
57 buffer_loc += size;
58 if (eot_count >= 0 && eot_count < 2)
59 eot_count++;
60 /* At the end of the tar file, libtar will add 2 blank blocks.
61 Once we have received both EOT blocks, we will immediately
62 write anything in the buffer to the file.
63 */
64
65 if (buffer_loc >= buffer_size || eot_count >= 2) {
66 flush = 1;
67 }
68 }
69 if (flush == 1) {
70 flush = 0;
71 if (buffer_loc == 0) {
72 // nothing to write
73 return 0;
74 }
75 if (write(fd, write_buffer, buffer_loc) != buffer_loc) {
Dees_Troy2673cec2013-04-02 20:22:16 +000076 LOGERR("Error writing tar file!\n");
Dees_Troye34c1332013-02-06 19:13:00 +000077 buffer_loc = 0;
78 return -1;
79 } else {
80 buffer_loc = 0;
81 return size;
82 }
83 } else {
84 return size;
85 }
86 // Shouldn't ever get here
87 return -1;
88}
89
90void flush_libtar_buffer(int fd) {
91 eot_count = 0;
92}