file_archive_extract_first_file can choose any file now

This commit is contained in:
Brad Parker 2016-09-18 21:04:05 -04:00
parent 082476f7b2
commit 2a75b88d89
5 changed files with 67 additions and 26 deletions

View File

@ -249,9 +249,22 @@ static int file_archive_extract_cb(const char *name, const char *valid_exts,
path_basename(name), sizeof(new_path));
userdata->first_extracted_file_path = strdup(new_path);
userdata->found_file = file_archive_perform_mode(new_path,
valid_exts, cdata, cmode, csize, size,
0, userdata);
char wanted_file[PATH_MAX_LENGTH] = {0};
const char *delim = path_get_archive_delim(userdata->archive_path);
if (delim)
strlcpy(wanted_file, delim + 1, strlen(delim) + 1);
if (!string_is_equal_noncase(userdata->extracted_file_path,
wanted_file))
return 1; // keep searching for the right file
if (file_archive_perform_mode(new_path,
valid_exts, cdata, cmode, csize, size,
0, userdata))
userdata->found_file = true;
return 0;
}
@ -466,18 +479,19 @@ int file_archive_parse_file_progress(file_archive_transfer_t *state)
}
/**
* file_archive_extract_first_file:
* file_archive_extract_file:
* @archive_path : filename path to archive.
* @archive_path_size : size of archive.
* @valid_exts : valid extensions for the file.
* @extraction_directory : the directory to extract temporary
* file to.
*
* Extract first file from archive.
* Extract file from archive. If no file inside the archive is
* specified, the first file found will be used.
*
* Returns : true (1) on success, otherwise false (0).
**/
bool file_archive_extract_first_file(
bool file_archive_extract_file(
char *archive_path,
size_t archive_path_size,
const char *valid_exts,
@ -506,6 +520,7 @@ bool file_archive_extract_first_file(
userdata.ext = list;
userdata.list = NULL;
userdata.context = NULL;
userdata.list_only = false;
if (!file_archive_parse_file(archive_path, valid_exts,
file_archive_extract_cb, &userdata))
@ -544,6 +559,7 @@ struct string_list *file_archive_get_file_list(const char *path,
const char *valid_exts)
{
struct archive_extract_userdata userdata = {0};
userdata.list_only = true;
userdata.list = string_list_new();

View File

@ -45,6 +45,8 @@ struct sevenzip_context_t {
ISzAlloc allocImp;
ISzAlloc allocTempImp;
CSzArEx db;
size_t temp_size;
uint32_t block_index;
uint32_t index;
uint32_t packIndex;
uint8_t *output;
@ -56,6 +58,8 @@ static void* sevenzip_stream_new(void)
struct sevenzip_context_t *sevenzip_context =
(struct sevenzip_context_t*)calloc(1, sizeof(struct sevenzip_context_t));
fprintf(stderr, "7z: stream new\n");
/* These are the allocation routines - currently using
* the non-standard 7zip choices. */
sevenzip_context->allocImp.Alloc = SzAlloc;
@ -64,6 +68,8 @@ static void* sevenzip_stream_new(void)
sevenzip_context->allocTempImp.Free = SzFreeTemp;
sevenzip_context->index = 0;
sevenzip_context->packIndex = 0;
sevenzip_context->temp_size = 0;
sevenzip_context->block_index = 0xFFFFFFFF;
sevenzip_context->output = NULL;
return sevenzip_context;
@ -73,6 +79,8 @@ static void sevenzip_stream_free(void *data)
{
struct sevenzip_context_t *sevenzip_context = (struct sevenzip_context_t*)data;
fprintf(stderr, "7z: stream free\n");
if (!sevenzip_context)
return;
@ -249,18 +257,6 @@ static int sevenzip_stream_decompress_data_to_file_iterate(void *data)
struct sevenzip_context_t *sevenzip_context =
(struct sevenzip_context_t*)data;
uint32_t block_index = 0xFFFFFFFF;
size_t offset = 0;
size_t outSizeProcessed = 0;
size_t output_size = 0;
SRes res = SzArEx_Extract(&sevenzip_context->db, &sevenzip_context->lookStream.s, sevenzip_context->index, &block_index,
&sevenzip_context->output, &output_size, &offset, &outSizeProcessed,
&sevenzip_context->allocImp, &sevenzip_context->allocTempImp);
if (res != SZ_OK)
return -1;
if (sevenzip_context->handle)
sevenzip_context->handle->data = sevenzip_context->output;
@ -283,6 +279,8 @@ static int sevenzip_parse_file_init(file_archive_transfer_t *state,
if (InFile_Open(&sevenzip_context->archiveStream.file, file))
return -1;
fprintf(stderr, "7z: open archive %s\n", file);
FileInStream_CreateVTable(&sevenzip_context->archiveStream);
LookToRead_CreateVTable(&sevenzip_context->lookStream, False);
sevenzip_context->lookStream.realStream = &sevenzip_context->archiveStream.s;
@ -300,9 +298,9 @@ static int sevenzip_parse_file_init(file_archive_transfer_t *state,
static int sevenzip_parse_file_iterate_step_internal(
file_archive_transfer_t *state, char *filename,
const uint8_t **cdata,
unsigned *cmode, uint32_t *size, uint32_t *csize,
uint32_t *checksum, unsigned *payback)
const uint8_t **cdata, unsigned *cmode,
uint32_t *size, uint32_t *csize, uint32_t *checksum,
unsigned *payback, struct archive_extract_userdata *userdata)
{
struct sevenzip_context_t *sevenzip_context = (struct sevenzip_context_t*)state->stream;
const CSzFileItem *file = sevenzip_context->db.db.Files + sevenzip_context->index;
@ -341,6 +339,24 @@ static int sevenzip_parse_file_iterate_step_internal(
strlcpy(filename, infile, PATH_MAX_LENGTH);
if (!userdata->list_only)
{
size_t output_size = 0;
size_t offset = 0;
size_t outSizeProcessed = 0;
res = SzArEx_Extract(&sevenzip_context->db,
&sevenzip_context->lookStream.s, sevenzip_context->index,
&sevenzip_context->block_index, &sevenzip_context->output,
&output_size, &offset, &outSizeProcessed,
&sevenzip_context->allocImp, &sevenzip_context->allocTempImp);
fprintf(stderr, "extract: %d\n", res == SZ_OK);
}
if (res != SZ_OK)
return -1;
*cmode = ARCHIVE_MODE_COMPRESSED;
*checksum = file->Crc;
*size = file->Size;
@ -366,11 +382,15 @@ static int sevenzip_parse_file_iterate_step(file_archive_transfer_t *state,
char filename[PATH_MAX_LENGTH] = {0};
int ret = sevenzip_parse_file_iterate_step_internal(state, filename,
&cdata, &cmode, &size, &csize,
&checksum, &payload);
&checksum, &payload, userdata);
if (ret != 1)
return ret;
userdata->extracted_file_path = filename;
fprintf(stderr, "set extracted path to %s\n", filename);
if (!file_cb(filename, valid_exts, cdata, cmode,
csize, size, checksum, userdata))
return 0;

View File

@ -447,6 +447,8 @@ static int zip_parse_file_iterate_step(file_archive_transfer_t *state,
if (ret != 1)
return ret;
userdata->extracted_file_path = filename;
if (!file_cb(filename, valid_exts, cdata, cmode,
csize, size, checksum, userdata))
return 0;

View File

@ -90,11 +90,13 @@ struct archive_extract_userdata
{
char *archive_path;
char *first_extracted_file_path;
char *extracted_file_path;
const char *extraction_directory;
size_t archive_path_size;
struct string_list *ext;
struct string_list *list;
bool found_file;
bool list_only;
void *context;
char archive_name[PATH_MAX_LENGTH];
uint32_t crc;
@ -151,18 +153,19 @@ void file_archive_parse_file_iterate_stop(file_archive_transfer_t *state);
int file_archive_parse_file_progress(file_archive_transfer_t *state);
/**
* file_archive_extract_first_file:
* file_archive_extract_file:
* @zip_path : filename path to ZIP archive.
* @zip_path_size : size of ZIP archive.
* @valid_exts : valid extensions for a file.
* @extraction_directory : the directory to extract temporary
* unzipped file to.
*
* Extract first file from archive.
* Extract file from archive. If no file inside the archive is
* specified, the first file found will be used.
*
* Returns : true (1) on success, otherwise false (0).
**/
bool file_archive_extract_first_file(char *zip_path, size_t zip_path_size,
bool file_archive_extract_file(char *zip_path, size_t zip_path_size,
const char *valid_exts, const char *extraction_dir,
char *out_path, size_t len);

View File

@ -525,7 +525,7 @@ static bool init_content_file_extract(
strlcpy(temp_content, content->elems[i].data,
sizeof(temp_content));
if (!file_archive_extract_first_file(temp_content,
if (!file_archive_extract_file(temp_content,
sizeof(temp_content), valid_ext,
*settings->directory.cache ?
settings->directory.cache : NULL,