Revamp Filter handling code.
1) Really avoid adding filter xattr for non-processed files. 2) Clean up filter error handling. 3) Avoid libarchive data writes in filter callbacks. 4) Have libarchive data writes in a single place. 5) Properly handle skipping filter processing for a file. 6) Fix temporary file pathname handling.
This commit is contained in:
parent
dfe18ef48f
commit
2cd41ec257
6 changed files with 223 additions and 104 deletions
|
@ -168,7 +168,6 @@ packjpg_filter(struct filter_info *fi, void *filter_private)
|
||||||
struct scratch_buffer *sdat = (struct scratch_buffer *)filter_private;
|
struct scratch_buffer *sdat = (struct scratch_buffer *)filter_private;
|
||||||
uchar_t *mapbuf, *out;
|
uchar_t *mapbuf, *out;
|
||||||
uint64_t len, in_size = 0, len1;
|
uint64_t len, in_size = 0, len1;
|
||||||
ssize_t rv;
|
|
||||||
|
|
||||||
len = archive_entry_size(fi->entry);
|
len = archive_entry_size(fi->entry);
|
||||||
len1 = len;
|
len1 = len;
|
||||||
|
@ -225,7 +224,13 @@ packjpg_filter(struct filter_info *fi, void *filter_private)
|
||||||
* version number. We also check if it is supported.
|
* version number. We also check if it is supported.
|
||||||
*/
|
*/
|
||||||
if (mapbuf[0] != 'J' || mapbuf[1] != 'S' || !pjg_version_supported(mapbuf[2])) {
|
if (mapbuf[0] != 'J' || mapbuf[1] != 'S' || !pjg_version_supported(mapbuf[2])) {
|
||||||
return (archive_write_data(fi->target_arc, sdat->in_buff, len));
|
uint8_t *out = malloc(len);
|
||||||
|
|
||||||
|
memcpy(out, sdat->in_buff, len);
|
||||||
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
|
return (FILTER_RETURN_SOFT_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,13 +247,11 @@ packjpg_filter(struct filter_info *fi, void *filter_private)
|
||||||
}
|
}
|
||||||
munmap(mapbuf, len1);
|
munmap(mapbuf, len1);
|
||||||
|
|
||||||
in_size = LE64(len);
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
rv = archive_write_data(fi->target_arc, &in_size, 8);
|
fi->fout->out = out;
|
||||||
if (rv != 8)
|
fi->fout->out_size = len;
|
||||||
return (rv);
|
fi->fout->hdr.in_size = LE64(len);
|
||||||
rv = archive_write_data(fi->target_arc, out, len);
|
return (ARCHIVE_OK);
|
||||||
free(out);
|
|
||||||
return (rv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -257,17 +260,23 @@ packjpg_filter(struct filter_info *fi, void *filter_private)
|
||||||
out = NULL;
|
out = NULL;
|
||||||
if ((len = packjpg_filter_process(mapbuf, in_size, &out)) == 0) {
|
if ((len = packjpg_filter_process(mapbuf, in_size, &out)) == 0) {
|
||||||
/*
|
/*
|
||||||
* If filter failed we write out the original data and indicate a
|
* If filter failed we indicate a soft error to continue the
|
||||||
* soft error to continue the archive extraction.
|
* archive extraction.
|
||||||
*/
|
*/
|
||||||
free(out);
|
free(out);
|
||||||
if (archive_write_data(fi->target_arc, mapbuf, len1) < len1)
|
out = malloc(len);
|
||||||
return (FILTER_RETURN_ERROR);
|
memcpy(out, sdat->in_buff, len);
|
||||||
|
|
||||||
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
return (FILTER_RETURN_SOFT_ERROR);
|
return (FILTER_RETURN_SOFT_ERROR);
|
||||||
}
|
}
|
||||||
rv = archive_write_data(fi->target_arc, out, len);
|
|
||||||
free(out);
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
return (rv);
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
|
@ -276,7 +285,6 @@ packpnm_filter(struct filter_info *fi, void *filter_private)
|
||||||
struct scratch_buffer *sdat = (struct scratch_buffer *)filter_private;
|
struct scratch_buffer *sdat = (struct scratch_buffer *)filter_private;
|
||||||
uchar_t *mapbuf, *out;
|
uchar_t *mapbuf, *out;
|
||||||
uint64_t len, in_size = 0, len1;
|
uint64_t len, in_size = 0, len1;
|
||||||
ssize_t rv;
|
|
||||||
|
|
||||||
len = archive_entry_size(fi->entry);
|
len = archive_entry_size(fi->entry);
|
||||||
len1 = len;
|
len1 = len;
|
||||||
|
@ -327,7 +335,13 @@ packpnm_filter(struct filter_info *fi, void *filter_private)
|
||||||
* Write the raw data and skip.
|
* Write the raw data and skip.
|
||||||
*/
|
*/
|
||||||
if (identify_pnm_type(mapbuf, len - 8) != 2) {
|
if (identify_pnm_type(mapbuf, len - 8) != 2) {
|
||||||
return (archive_write_data(fi->target_arc, sdat->in_buff, len));
|
uint8_t *out = malloc(len);
|
||||||
|
|
||||||
|
memcpy(out, sdat->in_buff, len);
|
||||||
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
|
return (FILTER_RETURN_SOFT_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,13 +358,11 @@ packpnm_filter(struct filter_info *fi, void *filter_private)
|
||||||
}
|
}
|
||||||
munmap(mapbuf, len1);
|
munmap(mapbuf, len1);
|
||||||
|
|
||||||
in_size = LE64(len);
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
rv = archive_write_data(fi->target_arc, &in_size, 8);
|
fi->fout->out = out;
|
||||||
if (rv != 8)
|
fi->fout->out_size = len;
|
||||||
return (rv);
|
fi->fout->hdr.in_size = LE64(len);
|
||||||
rv = archive_write_data(fi->target_arc, out, len);
|
return (ARCHIVE_OK);
|
||||||
free(out);
|
|
||||||
return (rv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -359,17 +371,23 @@ packpnm_filter(struct filter_info *fi, void *filter_private)
|
||||||
out = NULL;
|
out = NULL;
|
||||||
if ((len = packpnm_filter_process(mapbuf, in_size, &out)) == 0) {
|
if ((len = packpnm_filter_process(mapbuf, in_size, &out)) == 0) {
|
||||||
/*
|
/*
|
||||||
* If filter failed we write out the original data and indicate a
|
* If filter failed we indicate a soft error to continue the
|
||||||
* soft error to continue the archive extraction.
|
* archive extraction.
|
||||||
*/
|
*/
|
||||||
free(out);
|
free(out);
|
||||||
if (archive_write_data(fi->target_arc, mapbuf, len1) < len1)
|
out = malloc(len);
|
||||||
return (FILTER_RETURN_ERROR);
|
memcpy(out, sdat->in_buff, len);
|
||||||
|
|
||||||
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
return (FILTER_RETURN_SOFT_ERROR);
|
return (FILTER_RETURN_SOFT_ERROR);
|
||||||
}
|
}
|
||||||
rv = archive_write_data(fi->target_arc, out, len);
|
|
||||||
free(out);
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
return (rv);
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
#endif /* _MPLV2_LICENSE_ */
|
#endif /* _MPLV2_LICENSE_ */
|
||||||
|
|
||||||
|
@ -380,7 +398,6 @@ wavpack_filter(struct filter_info *fi, void *filter_private)
|
||||||
struct scratch_buffer *sdat = (struct scratch_buffer *)filter_private;
|
struct scratch_buffer *sdat = (struct scratch_buffer *)filter_private;
|
||||||
uchar_t *mapbuf, *out;
|
uchar_t *mapbuf, *out;
|
||||||
uint64_t len, in_size = 0, len1;
|
uint64_t len, in_size = 0, len1;
|
||||||
ssize_t rv;
|
|
||||||
|
|
||||||
len = archive_entry_size(fi->entry);
|
len = archive_entry_size(fi->entry);
|
||||||
len1 = len;
|
len1 = len;
|
||||||
|
@ -434,7 +451,13 @@ wavpack_filter(struct filter_info *fi, void *filter_private)
|
||||||
*/
|
*/
|
||||||
wpkstr = (char *)mapbuf;
|
wpkstr = (char *)mapbuf;
|
||||||
if (strncmp(wpkstr, "wvpk", 4) != 0) {
|
if (strncmp(wpkstr, "wvpk", 4) != 0) {
|
||||||
return (archive_write_data(fi->target_arc, sdat->in_buff, len));
|
uint8_t *out = malloc(len);
|
||||||
|
|
||||||
|
memcpy(out, sdat->in_buff, len);
|
||||||
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
|
return (FILTER_RETURN_SOFT_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,32 +474,36 @@ wavpack_filter(struct filter_info *fi, void *filter_private)
|
||||||
}
|
}
|
||||||
munmap(mapbuf, len1);
|
munmap(mapbuf, len1);
|
||||||
|
|
||||||
in_size = LE64(len1);
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
rv = archive_write_data(fi->target_arc, &in_size, 8);
|
fi->fout->out = out;
|
||||||
if (rv != 8)
|
fi->fout->out_size = len;
|
||||||
return (rv);
|
fi->fout->hdr.in_size = LE64(len1);
|
||||||
rv = archive_write_data(fi->target_arc, out, len);
|
return (ARCHIVE_OK);
|
||||||
free(out);
|
|
||||||
return (rv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decompression case.
|
* Decompression case.
|
||||||
*/
|
*/
|
||||||
out = NULL;
|
out = NULL;
|
||||||
if ((len = wavpack_filter_decode(mapbuf, len, &out, in_size)) == 0) {
|
if ((len = wavpack_filter_decode(mapbuf, in_size, &out, len)) == 0) {
|
||||||
/*
|
/*
|
||||||
* If filter failed we write out the original data and indicate a
|
* If filter failed we indicate a soft error to continue the
|
||||||
* soft error to continue the archive extraction.
|
* archive extraction.
|
||||||
*/
|
*/
|
||||||
free(out);
|
free(out);
|
||||||
if (archive_write_data(fi->target_arc, mapbuf, len1) < len1)
|
out = malloc(len);
|
||||||
return (FILTER_RETURN_ERROR);
|
memcpy(out, sdat->in_buff, len);
|
||||||
|
|
||||||
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
return (FILTER_RETURN_SOFT_ERROR);
|
return (FILTER_RETURN_SOFT_ERROR);
|
||||||
}
|
}
|
||||||
rv = archive_write_data(fi->target_arc, out, len);
|
|
||||||
free(out);
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
return (rv);
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
#endif /* _ENABLE_WAVPACK_ */
|
#endif /* _ENABLE_WAVPACK_ */
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,9 @@ extern "C" {
|
||||||
#define FILTER_RETURN_SOFT_ERROR (-2)
|
#define FILTER_RETURN_SOFT_ERROR (-2)
|
||||||
#define FILTER_XATTR_ENTRY "_._pc_filter_xattr"
|
#define FILTER_XATTR_ENTRY "_._pc_filter_xattr"
|
||||||
|
|
||||||
|
#define FILTER_OUTPUT_MEM 1
|
||||||
|
#define FILTER_OUTPUT_FILE 2
|
||||||
|
|
||||||
#define HELPER_DEF_BUFSIZ (512 * 1024)
|
#define HELPER_DEF_BUFSIZ (512 * 1024)
|
||||||
#define WVPK_FILE_SIZE_LIMIT (18 * 1024 * 1024)
|
#define WVPK_FILE_SIZE_LIMIT (18 * 1024 * 1024)
|
||||||
|
|
||||||
|
@ -57,6 +60,20 @@ extern "C" {
|
||||||
# define PJG_APPVERSION2 (25)
|
# define PJG_APPVERSION2 (25)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct _filter_std_hdr {
|
||||||
|
uint64_t in_size;
|
||||||
|
} filter_std_hdr_t;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
typedef struct _filter_output {
|
||||||
|
int output_type;
|
||||||
|
uint8_t *out;
|
||||||
|
size_t out_size;
|
||||||
|
int out_fd;
|
||||||
|
filter_std_hdr_t hdr;
|
||||||
|
} filter_output_t;
|
||||||
|
|
||||||
struct filter_info {
|
struct filter_info {
|
||||||
struct archive *source_arc;
|
struct archive *source_arc;
|
||||||
struct archive *target_arc;
|
struct archive *target_arc;
|
||||||
|
@ -65,6 +82,7 @@ struct filter_info {
|
||||||
int compressing, block_size;
|
int compressing, block_size;
|
||||||
int *type_ptr;
|
int *type_ptr;
|
||||||
int cmp_level;
|
int cmp_level;
|
||||||
|
filter_output_t *fout;
|
||||||
uchar_t scratch_buffer;
|
uchar_t scratch_buffer;
|
||||||
size_t scratch_buffer_size;
|
size_t scratch_buffer_size;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1022,8 +1022,8 @@ setup_extractor(pc_ctx_t *pctx)
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
process_by_filter(int fd, int *typ, struct archive *target_arc,
|
process_by_filter(int fd, int *typ, struct archive *target_arc,
|
||||||
struct archive *source_arc, struct archive_entry *entry, int cmp,
|
struct archive *source_arc, struct archive_entry *entry,
|
||||||
int level)
|
filter_output_t *fout, int cmp, int level)
|
||||||
{
|
{
|
||||||
struct filter_info fi;
|
struct filter_info fi;
|
||||||
int64_t wrtn;
|
int64_t wrtn;
|
||||||
|
@ -1036,9 +1036,10 @@ process_by_filter(int fd, int *typ, struct archive *target_arc,
|
||||||
fi.block_size = AW_BLOCK_SIZE;
|
fi.block_size = AW_BLOCK_SIZE;
|
||||||
fi.type_ptr = typ;
|
fi.type_ptr = typ;
|
||||||
fi.cmp_level = level;
|
fi.cmp_level = level;
|
||||||
|
fi.fout = fout;
|
||||||
wrtn = (*(typetab[(*typ >> 3)].filter_func))(&fi, typetab[(*typ >> 3)].filter_private);
|
wrtn = (*(typetab[(*typ >> 3)].filter_func))(&fi, typetab[(*typ >> 3)].filter_private);
|
||||||
if (wrtn == FILTER_RETURN_ERROR) {
|
if (wrtn == FILTER_RETURN_ERROR) {
|
||||||
log_msg(LOG_ERR, 0, "Error invoking filter module: %s",
|
log_msg(LOG_ERR, 0, "Warning: Error invoking filter: %s (skipping)",
|
||||||
typetab[(*typ >> 3)].filter_name);
|
typetab[(*typ >> 3)].filter_name);
|
||||||
}
|
}
|
||||||
return (wrtn);
|
return (wrtn);
|
||||||
|
@ -1075,6 +1076,7 @@ copy_file_data(pc_ctx_t *pctx, struct archive *arc, struct archive_entry *entry,
|
||||||
uchar_t *mapbuf;
|
uchar_t *mapbuf;
|
||||||
int rv, fd, typ1;
|
int rv, fd, typ1;
|
||||||
const char *fpath;
|
const char *fpath;
|
||||||
|
filter_output_t fout;
|
||||||
|
|
||||||
typ1 = typ;
|
typ1 = typ;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
@ -1093,21 +1095,40 @@ copy_file_data(pc_ctx_t *pctx, struct archive *arc, struct archive_entry *entry,
|
||||||
int64_t rv;
|
int64_t rv;
|
||||||
char *fname = typetab[(typ >> 3)].filter_name;
|
char *fname = typetab[(typ >> 3)].filter_name;
|
||||||
|
|
||||||
|
pctx->ctype = typ;
|
||||||
|
rv = process_by_filter(fd, &(pctx->ctype), arc, NULL, entry,
|
||||||
|
&fout, 1, pctx->level);
|
||||||
|
if (rv != FILTER_RETURN_SKIP &&
|
||||||
|
rv != FILTER_RETURN_ERROR) {
|
||||||
|
if (fout.output_type == FILTER_OUTPUT_MEM) {
|
||||||
archive_entry_xattr_add_entry(entry, FILTER_XATTR_ENTRY,
|
archive_entry_xattr_add_entry(entry, FILTER_XATTR_ENTRY,
|
||||||
fname, strlen(fname));
|
fname, strlen(fname));
|
||||||
if (write_header(arc, entry) == -1) {
|
if (write_header(arc, entry) == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
pctx->ctype = typ;
|
rv = archive_write_data(arc, &(fout.hdr),
|
||||||
rv = process_by_filter(fd, &(pctx->ctype), arc, NULL, entry,
|
sizeof (fout.hdr));
|
||||||
1, pctx->level);
|
if (rv != sizeof (fout.hdr))
|
||||||
if (rv == FILTER_RETURN_ERROR) {
|
return (rv);
|
||||||
|
rv = archive_write_data(arc, fout.out,
|
||||||
|
fout.out_size);
|
||||||
|
free(fout.out);
|
||||||
|
close(fd);
|
||||||
|
if (rv != fout.out_size)
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
else
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
} else {
|
||||||
|
log_msg(LOG_WARN, 0,
|
||||||
|
"Unsupported filter output for entry: %s.",
|
||||||
|
archive_entry_pathname(entry));
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (write_header(arc, entry) == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return (-1);
|
return (-1);
|
||||||
} else if (rv != FILTER_RETURN_SKIP) {
|
|
||||||
close(fd);
|
|
||||||
return (ARCHIVE_OK);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (write_header(arc, entry) == -1) {
|
if (write_header(arc, entry) == -1) {
|
||||||
|
@ -1150,26 +1171,46 @@ do_map:
|
||||||
int64_t rv;
|
int64_t rv;
|
||||||
char *fname = typetab[(typ >> 3)].filter_name;
|
char *fname = typetab[(typ >> 3)].filter_name;
|
||||||
|
|
||||||
archive_entry_xattr_add_entry(entry, FILTER_XATTR_ENTRY,
|
munmap(mapbuf, len);
|
||||||
|
rv = process_by_filter(fd, &(pctx->ctype), arc, NULL, entry,
|
||||||
|
&fout, 1, pctx->level);
|
||||||
|
if (rv != FILTER_RETURN_SKIP &&
|
||||||
|
rv != FILTER_RETURN_ERROR) {
|
||||||
|
if (fout.output_type == FILTER_OUTPUT_MEM) {
|
||||||
|
archive_entry_xattr_add_entry(entry,
|
||||||
|
FILTER_XATTR_ENTRY,
|
||||||
fname, strlen(fname));
|
fname, strlen(fname));
|
||||||
if (write_header(arc, entry) == -1) {
|
if (write_header(arc, entry) == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
rv = archive_write_data(arc, &(fout.hdr),
|
||||||
munmap(mapbuf, len);
|
sizeof (fout.hdr));
|
||||||
rv = process_by_filter(fd, &(pctx->ctype), arc, NULL, entry,
|
if (rv != sizeof (fout.hdr))
|
||||||
1, pctx->level);
|
return (rv);
|
||||||
if (rv == FILTER_RETURN_ERROR) {
|
rv = archive_write_data(arc, fout.out,
|
||||||
|
fout.out_size);
|
||||||
|
free(fout.out);
|
||||||
|
close(fd);
|
||||||
|
if (rv != fout.out_size)
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
else
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
} else {
|
||||||
|
log_msg(LOG_WARN, 0,
|
||||||
|
"Unsupported filter output for entry: %s.",
|
||||||
|
archive_entry_pathname(entry));
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (write_header(arc, entry) == -1) {
|
||||||
|
close(fd);
|
||||||
return (-1);
|
return (-1);
|
||||||
} else if (rv == FILTER_RETURN_SKIP) {
|
}
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
typ = TYPE_COMPRESSED;
|
typ = TYPE_COMPRESSED;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
goto do_map;
|
goto do_map;
|
||||||
} else {
|
|
||||||
return (ARCHIVE_OK);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (write_header(arc, entry) == -1) {
|
if (write_header(arc, entry) == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -1264,7 +1305,8 @@ archiver_thread_func(void *dat) {
|
||||||
if (rbytes == -1) break;
|
if (rbytes == -1) break;
|
||||||
archive_entry_copy_sourcepath(entry, fpath);
|
archive_entry_copy_sourcepath(entry, fpath);
|
||||||
if (archive_read_disk_entry_from_file(ard, entry, -1, NULL) != ARCHIVE_OK) {
|
if (archive_read_disk_entry_from_file(ard, entry, -1, NULL) != ARCHIVE_OK) {
|
||||||
log_msg(LOG_WARN, 1, "archive_read_disk_entry_from_file:\n %s", archive_error_string(ard));
|
log_msg(LOG_WARN, 1, "archive_read_disk_entry_from_file:\n %s",
|
||||||
|
archive_error_string(ard));
|
||||||
archive_entry_clear(entry);
|
archive_entry_clear(entry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1328,6 +1370,9 @@ archiver_thread_func(void *dat) {
|
||||||
ent = entry;
|
ent = entry;
|
||||||
while (ent != NULL) {
|
while (ent != NULL) {
|
||||||
if (write_entry(pctx, arc, ent, typ) != 0) {
|
if (write_entry(pctx, arc, ent, typ) != 0) {
|
||||||
|
log_msg(LOG_WARN, 1, "Error archiving entry: %s\n%s",
|
||||||
|
archive_entry_pathname(entry),
|
||||||
|
archive_error_string(ard));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ent = spare_entry;
|
ent = spare_entry;
|
||||||
|
@ -1370,42 +1415,63 @@ copy_data_out(struct archive *ar, struct archive *aw, struct archive_entry *entr
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
const void *buff;
|
const void *buff;
|
||||||
size_t size;
|
size_t size;
|
||||||
int r;
|
int r, ret;
|
||||||
|
filter_output_t fout;
|
||||||
|
|
||||||
|
ret = ARCHIVE_OK;
|
||||||
if (typ != TYPE_UNKNOWN) {
|
if (typ != TYPE_UNKNOWN) {
|
||||||
if (typetab[(typ >> 3)].filter_func != NULL) {
|
if (typetab[(typ >> 3)].filter_func != NULL) {
|
||||||
int64_t rv;
|
int64_t rv;
|
||||||
|
|
||||||
rv = process_by_filter(-1, &typ, aw, ar, entry, 0, 0);
|
rv = process_by_filter(-1, &typ, aw, ar, entry, &fout, 0, 0);
|
||||||
if (rv == FILTER_RETURN_ERROR) {
|
if (rv == FILTER_RETURN_ERROR) {
|
||||||
archive_set_error(ar, archive_errno(aw),
|
archive_set_error(ar, archive_errno(aw),
|
||||||
"%s", archive_error_string(aw));
|
"%s", archive_error_string(aw));
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
|
|
||||||
} else if (rv == FILTER_RETURN_SKIP) {
|
} else if (rv == FILTER_RETURN_SOFT_ERROR ||
|
||||||
log_msg(LOG_WARN, 0, "Filter function skipped.");
|
rv == FILTER_RETURN_SKIP) {
|
||||||
return (ARCHIVE_WARN);
|
if (rv == FILTER_RETURN_SKIP) {
|
||||||
|
log_msg(LOG_WARN, 0, "Filter function skipped"
|
||||||
} else if (rv == FILTER_RETURN_SOFT_ERROR) {
|
" for entry: %s.",
|
||||||
log_msg(LOG_WARN, 0, "Filter function failed for entry: %s.",
|
|
||||||
archive_entry_pathname(entry));
|
archive_entry_pathname(entry));
|
||||||
|
} else {
|
||||||
|
log_msg(LOG_WARN, 0, "Filter function failed"
|
||||||
|
" for entry: %s.",
|
||||||
|
archive_entry_pathname(entry));
|
||||||
|
}
|
||||||
pctx->errored_count++;
|
pctx->errored_count++;
|
||||||
if (pctx->err_paths_fd) {
|
if (pctx->err_paths_fd) {
|
||||||
fprintf(pctx->err_paths_fd, "%s,%s",
|
fprintf(pctx->err_paths_fd, "%s,%s\n",
|
||||||
archive_entry_pathname(entry),
|
archive_entry_pathname(entry),
|
||||||
typetab[(typ >> 3)].filter_name);
|
typetab[(typ >> 3)].filter_name);
|
||||||
}
|
}
|
||||||
return (ARCHIVE_WARN);
|
ret = ARCHIVE_WARN;
|
||||||
|
}
|
||||||
|
if (fout.output_type == FILTER_OUTPUT_MEM) {
|
||||||
|
int rv;
|
||||||
|
rv = archive_write_data(aw, fout.out, fout.out_size);
|
||||||
|
free(fout.out);
|
||||||
|
if (rv < ret)
|
||||||
|
ret = rv;
|
||||||
|
return (ret);
|
||||||
} else {
|
} else {
|
||||||
return (ARCHIVE_OK);
|
log_msg(LOG_WARN, 0,
|
||||||
|
"Unsupported filter output for entry: %s.",
|
||||||
|
archive_entry_pathname(entry));
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* If the filter above fails we fall through below to consume
|
||||||
|
* the data for the entry.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
r = archive_read_data_block(ar, &buff, &size, &offset);
|
r = archive_read_data_block(ar, &buff, &size, &offset);
|
||||||
if (r == ARCHIVE_EOF)
|
if (r == ARCHIVE_EOF)
|
||||||
return (ARCHIVE_OK);
|
break;
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
return (r);
|
return (r);
|
||||||
r = (int)archive_write_data_block(aw, buff, size, offset);
|
r = (int)archive_write_data_block(aw, buff, size, offset);
|
||||||
|
@ -1417,7 +1483,7 @@ copy_data_out(struct archive *ar, struct archive *aw, struct archive_entry *entr
|
||||||
return (r);
|
return (r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (ARCHIVE_OK);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1613,11 +1679,6 @@ extractor_thread_func(void *dat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
typ = TYPE_UNKNOWN;
|
typ = TYPE_UNKNOWN;
|
||||||
if (archive_entry_filetype(entry) == AE_IFREG) {
|
|
||||||
const char *fpath = archive_entry_pathname(entry);
|
|
||||||
typ = detect_type_by_ext(fpath, strlen(fpath));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Workaround for libarchive weirdness on Non MAC OS X platforms for filenames
|
* Workaround for libarchive weirdness on Non MAC OS X platforms for filenames
|
||||||
* starting with '._'. See above ...
|
* starting with '._'. See above ...
|
||||||
|
|
|
@ -327,7 +327,7 @@ wavpack_filter_encode(uchar_t *in_buf, size_t len, uchar_t **out_buf, int cmp_le
|
||||||
|
|
||||||
if (cmp_level < 6) {
|
if (cmp_level < 6) {
|
||||||
loc_config.flags |= CONFIG_FAST_FLAG;
|
loc_config.flags |= CONFIG_FAST_FLAG;
|
||||||
} else if (cmp_level > 8) {
|
} else if (cmp_level > 7) {
|
||||||
loc_config.flags |= CONFIG_HIGH_FLAG;
|
loc_config.flags |= CONFIG_HIGH_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
pcompress.c
16
pcompress.c
|
@ -1320,8 +1320,20 @@ start_decompress(pc_ctx_t *pctx, const char *filename, char *to_filename)
|
||||||
|
|
||||||
if (flags & FLAG_ARCHIVE) {
|
if (flags & FLAG_ARCHIVE) {
|
||||||
if (pctx->enable_rabin_global) {
|
if (pctx->enable_rabin_global) {
|
||||||
strcpy(pctx->archive_temp_file, to_filename);
|
char cwd[MAXPATHLEN];
|
||||||
strcat(pctx->archive_temp_file, "/.data");
|
|
||||||
|
if (to_filename[0] != PATHSEP_CHAR) {
|
||||||
|
if (getcwd(cwd, MAXPATHLEN) == NULL) {
|
||||||
|
log_msg(LOG_ERR, 1, "Cannot get current dir");
|
||||||
|
UNCOMP_BAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(pctx->archive_temp_file, sizeof (pctx->archive_temp_file),
|
||||||
|
"%s" PATHSEP_STR "%s" PATHSEP_STR ".data", cwd, to_filename);
|
||||||
|
} else {
|
||||||
|
snprintf(pctx->archive_temp_file, sizeof (pctx->archive_temp_file),
|
||||||
|
"%s" PATHSEP_STR ".data", to_filename);
|
||||||
|
}
|
||||||
if ((pctx->archive_temp_fd = open(pctx->archive_temp_file,
|
if ((pctx->archive_temp_fd = open(pctx->archive_temp_file,
|
||||||
O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) == -1) {
|
O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) == -1) {
|
||||||
log_msg(LOG_ERR, 1, "Cannot open temporary data file in "
|
log_msg(LOG_ERR, 1, "Cannot open temporary data file in "
|
||||||
|
|
|
@ -182,6 +182,7 @@ typedef int32_t bsize_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PATHSEP_CHAR '/'
|
#define PATHSEP_CHAR '/'
|
||||||
|
#define PATHSEP_STR "/"
|
||||||
#define BYTES_TO_MB(x) ((x) / (1024 * 1024))
|
#define BYTES_TO_MB(x) ((x) / (1024 * 1024))
|
||||||
#define U64_P(x) *((uint64_t *)(x))
|
#define U64_P(x) *((uint64_t *)(x))
|
||||||
#define U32_P(x) *((uint32_t *)(x))
|
#define U32_P(x) *((uint32_t *)(x))
|
||||||
|
|
Loading…
Reference in a new issue