summaryrefslogtreecommitdiffstats
path: root/tarWrite.c
diff options
context:
space:
mode:
Diffstat (limited to 'tarWrite.c')
-rw-r--r--tarWrite.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/tarWrite.c b/tarWrite.c
new file mode 100644
index 000000000..0f9a4a4b1
--- /dev/null
+++ b/tarWrite.c
@@ -0,0 +1,92 @@
+/*
+ Copyright 2013 bigbiff/Dees_Troy TeamWin
+ This file is part of TWRP/TeamWin Recovery Project.
+
+ TWRP is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ TWRP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with TWRP. If not, see <http://www.gnu.org/licenses/>.
+
+ This is a write buffer for use with libtar. Libtar normally writes
+ 512 bytes at a time but this results in poor file performance
+ especially on exFAT fuse file systems. This write buffer fixes that
+ problem.
+*/
+
+#include <fcntl.h>
+#include "libtar/libtar.h"
+#include "common.h"
+
+int flush = 0, eot_count = -1;
+unsigned char *write_buffer;
+unsigned buffer_size = 4096;
+unsigned buffer_loc = 0;
+
+void reinit_libtar_buffer(void) {
+ flush = 0;
+ eot_count = -1;
+ buffer_loc = 0;
+}
+
+void init_libtar_buffer(unsigned new_buff_size) {
+ if (new_buff_size != 0)
+ buffer_size = new_buff_size;
+
+ reinit_libtar_buffer();
+ write_buffer = (unsigned char*) malloc(sizeof(char *) * buffer_size);
+}
+
+void free_libtar_buffer(void) {
+ free(write_buffer);
+}
+
+ssize_t write_libtar_buffer(int fd, const void *buffer, size_t size) {
+ void* ptr;
+
+ if (flush == 0) {
+ ptr = write_buffer + buffer_loc;
+ memcpy(ptr, buffer, size);
+ buffer_loc += size;
+ if (eot_count >= 0 && eot_count < 2)
+ eot_count++;
+ /* At the end of the tar file, libtar will add 2 blank blocks.
+ Once we have received both EOT blocks, we will immediately
+ write anything in the buffer to the file.
+ */
+
+ if (buffer_loc >= buffer_size || eot_count >= 2) {
+ flush = 1;
+ }
+ }
+ if (flush == 1) {
+ flush = 0;
+ if (buffer_loc == 0) {
+ // nothing to write
+ return 0;
+ }
+ if (write(fd, write_buffer, buffer_loc) != buffer_loc) {
+ LOGE("Error writing tar file!\n");
+ buffer_loc = 0;
+ return -1;
+ } else {
+ buffer_loc = 0;
+ return size;
+ }
+ } else {
+ return size;
+ }
+ // Shouldn't ever get here
+ return -1;
+}
+
+void flush_libtar_buffer(int fd) {
+ eot_count = 0;
+}