22#include "ft_archive.h"
27#include <apr_file_io.h>
28#include <apr_strings.h>
34#include <archive_entry.h>
44static int copy_data(
struct archive *archive_read,
struct archive *archive_write)
46 const void *buff = NULL;
51 int result_value = archive_read_data_block(archive_read, &buff, &size, &offset);
52 if (result_value == ARCHIVE_EOF) {
55 if (result_value != ARCHIVE_OK) {
56 DEBUG_ERR(
"error calling archive_read_data_block(): %s", archive_error_string(archive_read));
59 result_value = (int) archive_write_data_block(archive_write, buff, size, offset);
60 if (result_value != ARCHIVE_OK) {
61 DEBUG_ERR(
"error calling archive_write_data_block(): %s", archive_error_string(archive_write));
67char *ft_archive_untar_file(ft_file_t *file, apr_pool_t *pool)
69 struct archive *archive_handle = NULL;
70 struct archive *ext = NULL;
71 struct archive_entry *entry = NULL;
75 archive_handle = archive_read_new();
76 if (NULL == archive_handle) {
77 DEBUG_ERR(
"error calling archive_read_new()");
80 result_value = archive_read_support_filter_all(archive_handle);
81 if (0 != result_value) {
82 DEBUG_ERR(
"error calling archive_read_support_filter_all(): %s", archive_error_string(archive_handle));
85 result_value = archive_read_support_format_all(archive_handle);
86 if (0 != result_value) {
87 DEBUG_ERR(
"error calling archive_read_support_format_all(): %s", archive_error_string(archive_handle));
90 result_value = archive_read_open_filename(archive_handle, file->path,
ARCHIVE_BLOCK_SIZE);
91 if (0 != result_value) {
92 DEBUG_ERR(
"error calling archive_read_open_filename(%s): %s", file->path, archive_error_string(archive_handle));
96 ext = archive_write_disk_new();
98 DEBUG_ERR(
"error calling archive_write_disk_new()");
103 result_value = archive_read_next_header(archive_handle, &entry);
104 if (result_value == ARCHIVE_EOF) {
105 DEBUG_ERR(
"subpath [%s] not found in archive [%s]", file->subpath, file->path);
108 if (result_value != ARCHIVE_OK) {
109 DEBUG_ERR(
"error in archive (%s): %s", file->path, archive_error_string(archive_handle));
113 if (!strcmp(file->subpath, archive_entry_pathname(entry))) {
114 mode_t current_mode = umask(S_IRWXG | S_IRWXO);
121 tmpfile = apr_pstrdup(pool,
"/tmp/ftwinXXXXXX");
122 result_value = mkstemp(tmpfile);
123 if (result_value < 0) {
124 DEBUG_ERR(
"error creating tmpfile %s", tmpfile);
130 archive_entry_copy_pathname(entry, tmpfile);
132 result_value = archive_write_header(ext, entry);
133 if (result_value == ARCHIVE_OK) {
134 result_value = copy_data(archive_handle, ext);
135 if (result_value != ARCHIVE_OK) {
136 DEBUG_ERR(
"error while copying data from archive (%s)", file->path);
137 (void) apr_file_remove(tmpfile, pool);
142 DEBUG_ERR(
"error in archive (%s): %s", file->path, archive_error_string(archive_handle));
143 (void) apr_file_remove(tmpfile, pool);
151 archive_write_free(ext);
152 archive_read_free(archive_handle);
UTIL debug output macros.
#define DEBUG_ERR(str, arg...)
Display error message at the level error.
static const size_t ARCHIVE_BLOCK_SIZE
The block size for archive operations.