mirror of
https://github.com/libretro/RetroArch
synced 2025-04-09 21:45:45 +00:00
task_decompress.c - add code for handling subdir extraction from
zip archive - needed for APK extraction
This commit is contained in:
parent
a7e72772e7
commit
6062467d1b
@ -671,6 +671,7 @@ static void config_set_defaults(void)
|
|||||||
settings->bundle_assets_extract_last_version = 0;
|
settings->bundle_assets_extract_last_version = 0;
|
||||||
*settings->bundle_assets_src_path = '\0';
|
*settings->bundle_assets_src_path = '\0';
|
||||||
*settings->bundle_assets_dst_path = '\0';
|
*settings->bundle_assets_dst_path = '\0';
|
||||||
|
*settings->bundle_assets_dst_path_subdir = '\0';
|
||||||
*settings->playlist_names = '\0';
|
*settings->playlist_names = '\0';
|
||||||
*settings->playlist_cores = '\0';
|
*settings->playlist_cores = '\0';
|
||||||
*settings->core_options_path = '\0';
|
*settings->core_options_path = '\0';
|
||||||
@ -1607,6 +1608,7 @@ static bool config_load_file(const char *path, bool set_defaults)
|
|||||||
CONFIG_GET_INT_BASE(conf, settings, bundle_assets_extract_last_version, "bundle_assets_extract_last_version");
|
CONFIG_GET_INT_BASE(conf, settings, bundle_assets_extract_last_version, "bundle_assets_extract_last_version");
|
||||||
config_get_array(conf, "bundle_assets_src_path", settings->bundle_assets_src_path, sizeof(settings->bundle_assets_src_path));
|
config_get_array(conf, "bundle_assets_src_path", settings->bundle_assets_src_path, sizeof(settings->bundle_assets_src_path));
|
||||||
config_get_array(conf, "bundle_assets_dst_path", settings->bundle_assets_dst_path, sizeof(settings->bundle_assets_dst_path));
|
config_get_array(conf, "bundle_assets_dst_path", settings->bundle_assets_dst_path, sizeof(settings->bundle_assets_dst_path));
|
||||||
|
config_get_array(conf, "bundle_assets_dst_path_subdir", settings->bundle_assets_dst_path_subdir, sizeof(settings->bundle_assets_dst_path_subdir));
|
||||||
|
|
||||||
CONFIG_GET_INT_BASE(conf, settings, rewind_granularity, "rewind_granularity");
|
CONFIG_GET_INT_BASE(conf, settings, rewind_granularity, "rewind_granularity");
|
||||||
CONFIG_GET_FLOAT_BASE(conf, settings, slowmotion_ratio, "slowmotion_ratio");
|
CONFIG_GET_FLOAT_BASE(conf, settings, slowmotion_ratio, "slowmotion_ratio");
|
||||||
@ -2541,6 +2543,7 @@ bool config_save_file(const char *path)
|
|||||||
config_set_int(conf, "bundle_assets_extract_last_version", settings->bundle_assets_extract_last_version);
|
config_set_int(conf, "bundle_assets_extract_last_version", settings->bundle_assets_extract_last_version);
|
||||||
config_set_string(conf, "bundle_assets_src_path", settings->bundle_assets_src_path);
|
config_set_string(conf, "bundle_assets_src_path", settings->bundle_assets_src_path);
|
||||||
config_set_string(conf, "bundle_assets_dst_path", settings->bundle_assets_dst_path);
|
config_set_string(conf, "bundle_assets_dst_path", settings->bundle_assets_dst_path);
|
||||||
|
config_set_string(conf, "bundle_assets_dst_path_subdir", settings->bundle_assets_dst_path_subdir);
|
||||||
config_set_string(conf, "playlist_names", settings->playlist_names);
|
config_set_string(conf, "playlist_names", settings->playlist_names);
|
||||||
config_set_string(conf, "playlist_cores", settings->playlist_cores);
|
config_set_string(conf, "playlist_cores", settings->playlist_cores);
|
||||||
config_set_float(conf, "video_refresh_rate", settings->video.refresh_rate);
|
config_set_float(conf, "video_refresh_rate", settings->video.refresh_rate);
|
||||||
|
@ -307,6 +307,7 @@ typedef struct settings
|
|||||||
unsigned bundle_assets_extract_last_version;
|
unsigned bundle_assets_extract_last_version;
|
||||||
char bundle_assets_src_path[PATH_MAX_LENGTH];
|
char bundle_assets_src_path[PATH_MAX_LENGTH];
|
||||||
char bundle_assets_dst_path[PATH_MAX_LENGTH];
|
char bundle_assets_dst_path[PATH_MAX_LENGTH];
|
||||||
|
char bundle_assets_dst_path_subdir[PATH_MAX_LENGTH];
|
||||||
|
|
||||||
char core_options_path[PATH_MAX_LENGTH];
|
char core_options_path[PATH_MAX_LENGTH];
|
||||||
char content_history_path[PATH_MAX_LENGTH];
|
char content_history_path[PATH_MAX_LENGTH];
|
||||||
|
@ -451,7 +451,7 @@ void cb_generic_download(void *task_data, void *user_data, const char *err)
|
|||||||
|
|
||||||
if (!strcasecmp(file_ext, "zip"))
|
if (!strcasecmp(file_ext, "zip"))
|
||||||
{
|
{
|
||||||
rarch_task_push_decompress(output_path, dir_path, NULL,
|
rarch_task_push_decompress(output_path, dir_path, NULL, NULL,
|
||||||
cb_decompressed, (void*)(uintptr_t)transf->type_hash);
|
cb_decompressed, (void*)(uintptr_t)transf->type_hash);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -281,8 +281,8 @@ void *menu_init(const void *data)
|
|||||||
settings->bundle_assets_extract_version_current != settings->bundle_assets_extract_last_version
|
settings->bundle_assets_extract_version_current != settings->bundle_assets_extract_last_version
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
rarch_task_push_decompress(settings->bundle_assets_src_path, settings->bundle_assets_dst_path, NULL,
|
rarch_task_push_decompress(settings->bundle_assets_src_path, settings->bundle_assets_dst_path,
|
||||||
bundle_decompressed, NULL);
|
settings->bundle_assets_dst_path_subdir, NULL, bundle_decompressed, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -25,8 +25,10 @@
|
|||||||
#include "../verbosity.h"
|
#include "../verbosity.h"
|
||||||
#include "../msg_hash.h"
|
#include "../msg_hash.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
char *source_file;
|
char *source_file;
|
||||||
|
char *subdir;
|
||||||
char *target_dir;
|
char *target_dir;
|
||||||
char *valid_ext;
|
char *valid_ext;
|
||||||
|
|
||||||
@ -35,6 +37,46 @@ typedef struct {
|
|||||||
zlib_transfer_t zlib;
|
zlib_transfer_t zlib;
|
||||||
} decompress_state_t;
|
} decompress_state_t;
|
||||||
|
|
||||||
|
static int file_decompressed_subdir(const char *name, const char *valid_exts,
|
||||||
|
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
||||||
|
uint32_t crc32, void *userdata)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX_LENGTH];
|
||||||
|
char path_dir[PATH_MAX_LENGTH];
|
||||||
|
decompress_state_t *dec = (decompress_state_t*)userdata;
|
||||||
|
|
||||||
|
/* Ignore directories. */
|
||||||
|
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
||||||
|
goto next_file;
|
||||||
|
|
||||||
|
if (strstr(name, dec->subdir) != name)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
name += strlen(dec->subdir) + 1;
|
||||||
|
|
||||||
|
fill_pathname_join(path, dec->target_dir, name, sizeof(path));
|
||||||
|
fill_pathname_basedir(path_dir, path, sizeof(path_dir));
|
||||||
|
|
||||||
|
/* Make directory */
|
||||||
|
if (!path_mkdir(path_dir))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!zlib_perform_mode(path, valid_exts,
|
||||||
|
cdata, cmode, csize, size, crc32, userdata))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
RARCH_LOG("[deflate subdir] Path: %s, CRC32: 0x%x\n", name, crc32);
|
||||||
|
|
||||||
|
next_file:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
error:
|
||||||
|
dec->callback_error = (char*)malloc(PATH_MAX_LENGTH);
|
||||||
|
snprintf(dec->callback_error, PATH_MAX_LENGTH, "Failed to deflate %s.\n", path);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int file_decompressed(const char *name, const char *valid_exts,
|
static int file_decompressed(const char *name, const char *valid_exts,
|
||||||
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
||||||
uint32_t crc32, void *userdata)
|
uint32_t crc32, void *userdata)
|
||||||
@ -71,14 +113,39 @@ error:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rarch_task_decompress_handler_finished(rarch_task_t *task,
|
||||||
|
decompress_state_t *dec)
|
||||||
|
{
|
||||||
|
|
||||||
|
task->finished = true;
|
||||||
|
|
||||||
|
if (!task->error && task->cancelled)
|
||||||
|
task->error = strdup("Task canceled");
|
||||||
|
|
||||||
|
if (!task->error)
|
||||||
|
{
|
||||||
|
decompress_task_data_t *data =
|
||||||
|
(decompress_task_data_t*)calloc(1, sizeof(*data));
|
||||||
|
|
||||||
|
data->source_file = dec->source_file;
|
||||||
|
task->task_data = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
free(dec->source_file);
|
||||||
|
|
||||||
|
if (dec->subdir)
|
||||||
|
free(dec->subdir);
|
||||||
|
if (dec->valid_ext)
|
||||||
|
free(dec->valid_ext);
|
||||||
|
free(dec->target_dir);
|
||||||
|
free(dec);
|
||||||
|
}
|
||||||
|
|
||||||
static void rarch_task_decompress_handler(rarch_task_t *task)
|
static void rarch_task_decompress_handler(rarch_task_t *task)
|
||||||
{
|
{
|
||||||
decompress_state_t *dec = (decompress_state_t*)task->state;
|
|
||||||
decompress_task_data_t *data = NULL;
|
|
||||||
bool returnerr;
|
bool returnerr;
|
||||||
int ret = 0;
|
decompress_state_t *dec = (decompress_state_t*)task->state;
|
||||||
|
int ret = zlib_parse_file_iterate(&dec->zlib, &returnerr, dec->source_file,
|
||||||
ret = zlib_parse_file_iterate(&dec->zlib, &returnerr, dec->source_file,
|
|
||||||
dec->valid_ext, file_decompressed, dec);
|
dec->valid_ext, file_decompressed, dec);
|
||||||
|
|
||||||
task->progress = zlib_parse_file_progress(&dec->zlib);
|
task->progress = zlib_parse_file_progress(&dec->zlib);
|
||||||
@ -87,30 +154,27 @@ static void rarch_task_decompress_handler(rarch_task_t *task)
|
|||||||
{
|
{
|
||||||
task->error = dec->callback_error;
|
task->error = dec->callback_error;
|
||||||
zlib_parse_file_iterate_stop(&dec->zlib);
|
zlib_parse_file_iterate_stop(&dec->zlib);
|
||||||
goto task_finished;
|
|
||||||
|
rarch_task_decompress_handler_finished(task, dec);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
static void rarch_task_decompress_handler_subdir(rarch_task_t *task)
|
||||||
|
{
|
||||||
|
bool returnerr;
|
||||||
|
decompress_state_t *dec = (decompress_state_t*)task->state;
|
||||||
|
int ret = zlib_parse_file_iterate(&dec->zlib, &returnerr, dec->source_file,
|
||||||
|
dec->valid_ext, file_decompressed_subdir, dec);
|
||||||
|
|
||||||
task_finished:
|
task->progress = zlib_parse_file_progress(&dec->zlib);
|
||||||
task->finished = true;
|
|
||||||
|
|
||||||
if (!task->error && task->cancelled)
|
if (task->cancelled || ret != 0)
|
||||||
task->error = strdup("Task canceled");
|
|
||||||
|
|
||||||
if (!task->error)
|
|
||||||
{
|
{
|
||||||
data = (decompress_task_data_t*)calloc(1, sizeof(*data));
|
task->error = dec->callback_error;
|
||||||
data->source_file = dec->source_file;
|
zlib_parse_file_iterate_stop(&dec->zlib);
|
||||||
task->task_data = data;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
free(dec->source_file);
|
|
||||||
|
|
||||||
if (dec->valid_ext)
|
rarch_task_decompress_handler_finished(task, dec);
|
||||||
free(dec->valid_ext);
|
}
|
||||||
free(dec->target_dir);
|
|
||||||
free(dec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rarch_task_decompress_finder(rarch_task_t *task, void *user_data)
|
static bool rarch_task_decompress_finder(rarch_task_t *task, void *user_data)
|
||||||
@ -124,7 +188,7 @@ static bool rarch_task_decompress_finder(rarch_task_t *task, void *user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool rarch_task_push_decompress(const char *source_file, const char *target_dir,
|
bool rarch_task_push_decompress(const char *source_file, const char *target_dir,
|
||||||
const char *valid_ext, rarch_task_callback_t cb, void *user_data)
|
const char *subdir, const char *valid_ext, rarch_task_callback_t cb, void *user_data)
|
||||||
{
|
{
|
||||||
decompress_state_t *s;
|
decompress_state_t *s;
|
||||||
rarch_task_t *t;
|
rarch_task_t *t;
|
||||||
@ -166,8 +230,14 @@ bool rarch_task_push_decompress(const char *source_file, const char *target_dir,
|
|||||||
s->zlib.type = ZLIB_TRANSFER_INIT;
|
s->zlib.type = ZLIB_TRANSFER_INIT;
|
||||||
|
|
||||||
t = (rarch_task_t*)calloc(1, sizeof(*t));
|
t = (rarch_task_t*)calloc(1, sizeof(*t));
|
||||||
t->handler = rarch_task_decompress_handler;
|
|
||||||
t->state = s;
|
t->state = s;
|
||||||
|
t->handler = rarch_task_decompress_handler;
|
||||||
|
|
||||||
|
if (subdir && subdir[0] != '\0')
|
||||||
|
{
|
||||||
|
s->subdir = strdup(subdir);
|
||||||
|
t->handler = rarch_task_decompress_handler_subdir;
|
||||||
|
}
|
||||||
|
|
||||||
t->callback = cb;
|
t->callback = cb;
|
||||||
t->user_data = user_data;
|
t->user_data = user_data;
|
||||||
|
@ -163,7 +163,8 @@ typedef struct {
|
|||||||
} decompress_task_data_t;
|
} decompress_task_data_t;
|
||||||
|
|
||||||
bool rarch_task_push_decompress(const char *source_file, const char *target_dir,
|
bool rarch_task_push_decompress(const char *source_file, const char *target_dir,
|
||||||
const char *valid_ext, rarch_task_callback_t cb, void *user_data);
|
const char *subdir, const char *valid_ext,
|
||||||
|
rarch_task_callback_t cb, void *user_data);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user