mirror of
https://github.com/libretro/RetroArch
synced 2025-04-01 13:20:43 +00:00
fix more memory corruption
This commit is contained in:
parent
dc4760f5a6
commit
a7ffead8f6
@ -182,13 +182,11 @@ static int file_archive_get_file_list_cb(
|
|||||||
uint32_t csize,
|
uint32_t csize,
|
||||||
uint32_t size,
|
uint32_t size,
|
||||||
uint32_t checksum,
|
uint32_t checksum,
|
||||||
void *userdata)
|
struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
union string_list_elem_attr attr;
|
union string_list_elem_attr attr;
|
||||||
struct string_list *ext_list = NULL;
|
struct string_list *ext_list = NULL;
|
||||||
const char *file_ext = NULL;
|
const char *file_ext = NULL;
|
||||||
struct archive_extract_userdata *data =
|
|
||||||
(struct archive_extract_userdata*)userdata;
|
|
||||||
size_t pathLen = strlen(path);
|
size_t pathLen = strlen(path);
|
||||||
|
|
||||||
(void)cdata;
|
(void)cdata;
|
||||||
@ -224,7 +222,7 @@ static int file_archive_get_file_list_cb(
|
|||||||
string_list_free(ext_list);
|
string_list_free(ext_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string_list_append(data->list, path, attr);
|
return string_list_append(userdata->list, path, attr);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
string_list_free(ext_list);
|
string_list_free(ext_list);
|
||||||
@ -234,28 +232,26 @@ error:
|
|||||||
static int file_archive_extract_cb(const char *name, const char *valid_exts,
|
static int file_archive_extract_cb(const char *name, const char *valid_exts,
|
||||||
const uint8_t *cdata,
|
const uint8_t *cdata,
|
||||||
unsigned cmode, uint32_t csize, uint32_t size,
|
unsigned cmode, uint32_t csize, uint32_t size,
|
||||||
uint32_t checksum, void *userdata)
|
uint32_t checksum, struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
const char *ext = path_get_extension(name);
|
const char *ext = path_get_extension(name);
|
||||||
struct archive_extract_userdata *data = (struct archive_extract_userdata*)
|
|
||||||
userdata;
|
|
||||||
|
|
||||||
/* Extract first file that matches our list. */
|
/* Extract first file that matches our list. */
|
||||||
if (ext && string_list_find_elem(data->ext, ext))
|
if (ext && string_list_find_elem(userdata->ext, ext))
|
||||||
{
|
{
|
||||||
char new_path[PATH_MAX_LENGTH] = {0};
|
char new_path[PATH_MAX_LENGTH] = {0};
|
||||||
|
|
||||||
if (data->extraction_directory)
|
if (userdata->extraction_directory)
|
||||||
fill_pathname_join(new_path, data->extraction_directory,
|
fill_pathname_join(new_path, userdata->extraction_directory,
|
||||||
path_basename(name), sizeof(new_path));
|
path_basename(name), sizeof(new_path));
|
||||||
else
|
else
|
||||||
fill_pathname_resolve_relative(new_path, data->archive_path,
|
fill_pathname_resolve_relative(new_path, userdata->archive_path,
|
||||||
path_basename(name), sizeof(new_path));
|
path_basename(name), sizeof(new_path));
|
||||||
|
|
||||||
data->first_extracted_file_path = strdup(new_path);
|
userdata->first_extracted_file_path = strdup(new_path);
|
||||||
data->found_file = file_archive_perform_mode(new_path,
|
userdata->found_file = file_archive_perform_mode(new_path,
|
||||||
valid_exts, cdata, cmode, csize, size,
|
valid_exts, cdata, cmode, csize, size,
|
||||||
0, data);
|
0, userdata);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,7 +357,7 @@ int file_archive_parse_file_iterate(
|
|||||||
const char *file,
|
const char *file,
|
||||||
const char *valid_exts,
|
const char *valid_exts,
|
||||||
file_archive_file_cb file_cb,
|
file_archive_file_cb file_cb,
|
||||||
void *userdata)
|
struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
if (!state)
|
if (!state)
|
||||||
return -1;
|
return -1;
|
||||||
@ -373,10 +369,8 @@ int file_archive_parse_file_iterate(
|
|||||||
case ARCHIVE_TRANSFER_INIT:
|
case ARCHIVE_TRANSFER_INIT:
|
||||||
if (file_archive_parse_file_init(state, file) == 0)
|
if (file_archive_parse_file_init(state, file) == 0)
|
||||||
{
|
{
|
||||||
struct archive_extract_userdata *data =
|
if (userdata)
|
||||||
(struct archive_extract_userdata*)userdata;
|
userdata->context = state->stream;
|
||||||
if (data)
|
|
||||||
data->context = state->stream;
|
|
||||||
state->type = ARCHIVE_TRANSFER_ITERATE;
|
state->type = ARCHIVE_TRANSFER_ITERATE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -384,7 +378,7 @@ int file_archive_parse_file_iterate(
|
|||||||
break;
|
break;
|
||||||
case ARCHIVE_TRANSFER_ITERATE:
|
case ARCHIVE_TRANSFER_ITERATE:
|
||||||
{
|
{
|
||||||
const struct file_archive_file_backend *backend =
|
const struct file_archive_file_backend *backend =
|
||||||
file_archive_get_file_backend(file);
|
file_archive_get_file_backend(file);
|
||||||
|
|
||||||
if (backend)
|
if (backend)
|
||||||
@ -413,8 +407,6 @@ int file_archive_parse_file_iterate(
|
|||||||
}
|
}
|
||||||
if (state->stream && state->backend)
|
if (state->stream && state->backend)
|
||||||
{
|
{
|
||||||
struct archive_extract_userdata *data =
|
|
||||||
(struct archive_extract_userdata*)userdata;
|
|
||||||
state->backend->stream_free(state->stream);
|
state->backend->stream_free(state->stream);
|
||||||
|
|
||||||
if (state->stream)
|
if (state->stream)
|
||||||
@ -422,8 +414,8 @@ int file_archive_parse_file_iterate(
|
|||||||
|
|
||||||
state->stream = NULL;
|
state->stream = NULL;
|
||||||
|
|
||||||
if (data)
|
if (userdata)
|
||||||
data->context = NULL;
|
userdata->context = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -449,7 +441,7 @@ int file_archive_parse_file_iterate(
|
|||||||
* Returns: true (1) on success, otherwise false (0).
|
* Returns: true (1) on success, otherwise false (0).
|
||||||
**/
|
**/
|
||||||
static bool file_archive_parse_file(const char *file, const char *valid_exts,
|
static bool file_archive_parse_file(const char *file, const char *valid_exts,
|
||||||
file_archive_file_cb file_cb, void *userdata)
|
file_archive_file_cb file_cb, struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
file_archive_transfer_t state = {0};
|
file_archive_transfer_t state = {0};
|
||||||
bool returnerr = true;
|
bool returnerr = true;
|
||||||
@ -572,7 +564,7 @@ error:
|
|||||||
|
|
||||||
bool file_archive_perform_mode(const char *path, const char *valid_exts,
|
bool file_archive_perform_mode(const char *path, 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, struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
switch (cmode)
|
switch (cmode)
|
||||||
{
|
{
|
||||||
@ -585,10 +577,9 @@ bool file_archive_perform_mode(const char *path, const char *valid_exts,
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
file_archive_file_handle_t handle = {0};
|
file_archive_file_handle_t handle = {0};
|
||||||
struct archive_extract_userdata *data = (struct archive_extract_userdata*)userdata;
|
|
||||||
|
|
||||||
handle.backend = file_archive_get_file_backend(data->archive_path);
|
handle.backend = file_archive_get_file_backend(userdata->archive_path);
|
||||||
handle.stream = data->context;
|
handle.stream = userdata->context;
|
||||||
|
|
||||||
if (!handle.backend->stream_decompress_data_to_file_init(&handle,
|
if (!handle.backend->stream_decompress_data_to_file_init(&handle,
|
||||||
cdata, csize, size))
|
cdata, csize, size))
|
||||||
|
@ -344,7 +344,7 @@ static int sevenzip_parse_file_iterate_step_internal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int sevenzip_parse_file_iterate_step(file_archive_transfer_t *state,
|
static int sevenzip_parse_file_iterate_step(file_archive_transfer_t *state,
|
||||||
const char *valid_exts, void *userdata, file_archive_file_cb file_cb)
|
const char *valid_exts, struct archive_extract_userdata *userdata, file_archive_file_cb file_cb)
|
||||||
{
|
{
|
||||||
const uint8_t *cdata = NULL;
|
const uint8_t *cdata = NULL;
|
||||||
uint32_t checksum = 0;
|
uint32_t checksum = 0;
|
||||||
|
@ -208,15 +208,6 @@ static uint32_t zlib_stream_crc32_calculate(uint32_t crc,
|
|||||||
return encoding_crc32(crc, data, length);
|
return encoding_crc32(crc, data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct decomp_state
|
|
||||||
{
|
|
||||||
char *opt_file;
|
|
||||||
char *needle;
|
|
||||||
void **buf;
|
|
||||||
size_t size;
|
|
||||||
bool found;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool zip_file_decompressed_handle(
|
static bool zip_file_decompressed_handle(
|
||||||
file_archive_file_handle_t *handle,
|
file_archive_file_handle_t *handle,
|
||||||
const uint8_t *cdata, uint32_t csize,
|
const uint8_t *cdata, uint32_t csize,
|
||||||
@ -270,10 +261,8 @@ static int zip_file_decompressed(
|
|||||||
const char *name, const char *valid_exts,
|
const char *name, const char *valid_exts,
|
||||||
const uint8_t *cdata, unsigned cmode,
|
const uint8_t *cdata, unsigned cmode,
|
||||||
uint32_t csize, uint32_t size,
|
uint32_t csize, uint32_t size,
|
||||||
uint32_t crc32, void *userdata)
|
uint32_t crc32, struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
struct decomp_state *st = (struct decomp_state*)userdata;
|
|
||||||
|
|
||||||
/* Ignore directories. */
|
/* Ignore directories. */
|
||||||
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
||||||
return 1;
|
return 1;
|
||||||
@ -282,17 +271,17 @@ static int zip_file_decompressed(
|
|||||||
RARCH_LOG("[deflate] Path: %s, CRC32: 0x%x\n", name, crc32);
|
RARCH_LOG("[deflate] Path: %s, CRC32: 0x%x\n", name, crc32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (strstr(name, st->needle))
|
if (strstr(name, userdata->decomp_state.needle))
|
||||||
{
|
{
|
||||||
bool goto_error = false;
|
bool goto_error = false;
|
||||||
file_archive_file_handle_t handle = {0};
|
file_archive_file_handle_t handle = {0};
|
||||||
|
|
||||||
st->found = true;
|
userdata->decomp_state.found = true;
|
||||||
|
|
||||||
if (zip_file_decompressed_handle(&handle,
|
if (zip_file_decompressed_handle(&handle,
|
||||||
cdata, csize, size, crc32))
|
cdata, csize, size, crc32))
|
||||||
{
|
{
|
||||||
if (st->opt_file != 0)
|
if (userdata->decomp_state.opt_file != 0)
|
||||||
{
|
{
|
||||||
/* Called in case core has need_fullpath enabled. */
|
/* Called in case core has need_fullpath enabled. */
|
||||||
char *buf = (char*)malloc(size);
|
char *buf = (char*)malloc(size);
|
||||||
@ -301,26 +290,26 @@ static int zip_file_decompressed(
|
|||||||
{
|
{
|
||||||
/*RARCH_LOG("%s: %s\n",
|
/*RARCH_LOG("%s: %s\n",
|
||||||
msg_hash_to_str(MSG_EXTRACTING_FILE),
|
msg_hash_to_str(MSG_EXTRACTING_FILE),
|
||||||
st->opt_file);*/
|
userdata->decomp_state.opt_file);*/
|
||||||
memcpy(buf, handle.data, size);
|
memcpy(buf, handle.data, size);
|
||||||
|
|
||||||
if (!filestream_write_file(st->opt_file, buf, size))
|
if (!filestream_write_file(userdata->decomp_state.opt_file, buf, size))
|
||||||
goto_error = true;
|
goto_error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
st->size = 0;
|
userdata->decomp_state.size = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Called in case core has need_fullpath disabled.
|
/* Called in case core has need_fullpath disabled.
|
||||||
* Will copy decompressed content directly into
|
* Will copy decompressed content directly into
|
||||||
* RetroArch's ROM buffer. */
|
* RetroArch's ROM buffer. */
|
||||||
*st->buf = malloc(size);
|
*userdata->decomp_state.buf = malloc(size);
|
||||||
memcpy(*st->buf, handle.data, size);
|
memcpy(*userdata->decomp_state.buf, handle.data, size);
|
||||||
|
|
||||||
st->size = size;
|
userdata->decomp_state.size = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,41 +329,41 @@ static int zip_file_read(
|
|||||||
const char *optional_outfile)
|
const char *optional_outfile)
|
||||||
{
|
{
|
||||||
file_archive_transfer_t zlib;
|
file_archive_transfer_t zlib;
|
||||||
struct decomp_state st;
|
|
||||||
bool returnerr = true;
|
bool returnerr = true;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
struct archive_extract_userdata userdata = {0};
|
||||||
|
|
||||||
zlib.type = ARCHIVE_TRANSFER_INIT;
|
zlib.type = ARCHIVE_TRANSFER_INIT;
|
||||||
|
|
||||||
st.needle = NULL;
|
userdata.decomp_state.needle = NULL;
|
||||||
st.opt_file = NULL;
|
userdata.decomp_state.opt_file = NULL;
|
||||||
st.found = false;
|
userdata.decomp_state.found = false;
|
||||||
st.buf = buf;
|
userdata.decomp_state.buf = buf;
|
||||||
|
|
||||||
if (needle)
|
if (needle)
|
||||||
st.needle = strdup(needle);
|
userdata.decomp_state.needle = strdup(needle);
|
||||||
if (optional_outfile)
|
if (optional_outfile)
|
||||||
st.opt_file = strdup(optional_outfile);
|
userdata.decomp_state.opt_file = strdup(optional_outfile);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = file_archive_parse_file_iterate(&zlib, &returnerr, path,
|
ret = file_archive_parse_file_iterate(&zlib, &returnerr, path,
|
||||||
"", zip_file_decompressed, &st);
|
"", zip_file_decompressed, &userdata);
|
||||||
if (!returnerr)
|
if (!returnerr)
|
||||||
break;
|
break;
|
||||||
}while(ret == 0 && !st.found);
|
}while(ret == 0 && !userdata.decomp_state.found);
|
||||||
|
|
||||||
file_archive_parse_file_iterate_stop(&zlib);
|
file_archive_parse_file_iterate_stop(&zlib);
|
||||||
|
|
||||||
if (st.opt_file)
|
if (userdata.decomp_state.opt_file)
|
||||||
free(st.opt_file);
|
free(userdata.decomp_state.opt_file);
|
||||||
if (st.needle)
|
if (userdata.decomp_state.needle)
|
||||||
free(st.needle);
|
free(userdata.decomp_state.needle);
|
||||||
|
|
||||||
if (!st.found)
|
if (!userdata.decomp_state.found)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return st.size;
|
return userdata.decomp_state.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zip_parse_file_init(file_archive_transfer_t *state,
|
static int zip_parse_file_init(file_archive_transfer_t *state,
|
||||||
@ -442,7 +431,7 @@ static int zip_parse_file_iterate_step_internal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int zip_parse_file_iterate_step(file_archive_transfer_t *state,
|
static int zip_parse_file_iterate_step(file_archive_transfer_t *state,
|
||||||
const char *valid_exts, void *userdata, file_archive_file_cb file_cb)
|
const char *valid_exts, struct archive_extract_userdata *userdata, file_archive_file_cb file_cb)
|
||||||
{
|
{
|
||||||
const uint8_t *cdata = NULL;
|
const uint8_t *cdata = NULL;
|
||||||
uint32_t checksum = 0;
|
uint32_t checksum = 0;
|
||||||
|
@ -25,9 +25,10 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <boolean.h>
|
#include <boolean.h>
|
||||||
|
|
||||||
|
#include <retro_miscellaneous.h>
|
||||||
|
|
||||||
enum file_archive_transfer_type
|
enum file_archive_transfer_type
|
||||||
{
|
{
|
||||||
ARCHIVE_TRANSFER_NONE = 0,
|
ARCHIVE_TRANSFER_NONE = 0,
|
||||||
@ -63,6 +64,28 @@ enum file_archive_compression_mode
|
|||||||
ARCHIVE_MODE_COMPRESSED = 8
|
ARCHIVE_MODE_COMPRESSED = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct decomp_state_t
|
||||||
|
{
|
||||||
|
char *opt_file;
|
||||||
|
char *needle;
|
||||||
|
void **buf;
|
||||||
|
size_t size;
|
||||||
|
bool found;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *source_file;
|
||||||
|
char *subdir;
|
||||||
|
char *target_dir;
|
||||||
|
char *target_file;
|
||||||
|
char *valid_ext;
|
||||||
|
|
||||||
|
char *callback_error;
|
||||||
|
|
||||||
|
file_archive_transfer_t archive;
|
||||||
|
} decompress_state_t;
|
||||||
|
|
||||||
struct archive_extract_userdata
|
struct archive_extract_userdata
|
||||||
{
|
{
|
||||||
char *archive_path;
|
char *archive_path;
|
||||||
@ -73,12 +96,16 @@ struct archive_extract_userdata
|
|||||||
struct string_list *list;
|
struct string_list *list;
|
||||||
bool found_file;
|
bool found_file;
|
||||||
void *context;
|
void *context;
|
||||||
|
char archive_name[PATH_MAX_LENGTH];
|
||||||
|
uint32_t crc;
|
||||||
|
struct decomp_state_t decomp_state;
|
||||||
|
decompress_state_t dec;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Returns true when parsing should continue. False to stop. */
|
/* Returns true when parsing should continue. False to stop. */
|
||||||
typedef int (*file_archive_file_cb)(const char *name, const char *valid_exts,
|
typedef int (*file_archive_file_cb)(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, struct archive_extract_userdata *userdata);
|
||||||
|
|
||||||
struct file_archive_file_backend
|
struct file_archive_file_backend
|
||||||
{
|
{
|
||||||
@ -106,7 +133,7 @@ struct file_archive_file_backend
|
|||||||
int (*archive_parse_file_iterate_step)(
|
int (*archive_parse_file_iterate_step)(
|
||||||
file_archive_transfer_t *state,
|
file_archive_transfer_t *state,
|
||||||
const char *valid_exts,
|
const char *valid_exts,
|
||||||
void *userdata,
|
struct archive_extract_userdata *userdata,
|
||||||
file_archive_file_cb file_cb);
|
file_archive_file_cb file_cb);
|
||||||
const char *ident;
|
const char *ident;
|
||||||
};
|
};
|
||||||
@ -117,7 +144,7 @@ int file_archive_parse_file_iterate(
|
|||||||
const char *file,
|
const char *file,
|
||||||
const char *valid_exts,
|
const char *valid_exts,
|
||||||
file_archive_file_cb file_cb,
|
file_archive_file_cb file_cb,
|
||||||
void *userdata);
|
struct archive_extract_userdata *userdata);
|
||||||
|
|
||||||
void file_archive_parse_file_iterate_stop(file_archive_transfer_t *state);
|
void file_archive_parse_file_iterate_stop(file_archive_transfer_t *state);
|
||||||
|
|
||||||
@ -151,7 +178,7 @@ struct string_list* file_archive_get_file_list(const char *path, const char *val
|
|||||||
|
|
||||||
bool file_archive_perform_mode(const char *name, const char *valid_exts,
|
bool file_archive_perform_mode(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, struct archive_extract_userdata *userdata);
|
||||||
|
|
||||||
void file_archive_deflate_init(void *data, int level);
|
void file_archive_deflate_init(void *data, int level);
|
||||||
|
|
||||||
|
@ -66,13 +66,9 @@ typedef struct db_handle
|
|||||||
#ifdef HAVE_COMPRESSION
|
#ifdef HAVE_COMPRESSION
|
||||||
static int archive_compare_crc32(const char *name, const char *valid_exts,
|
static int archive_compare_crc32(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, struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
database_state_handle_t *db_state = (database_state_handle_t*)userdata;
|
userdata->crc = crc32;
|
||||||
|
|
||||||
db_state->crc = crc32;
|
|
||||||
|
|
||||||
strlcpy(db_state->archive_name, name, sizeof(db_state->archive_name));
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
RARCH_LOG("Going to compare CRC 0x%x for %s\n", crc32, name);
|
RARCH_LOG("Going to compare CRC 0x%x for %s\n", crc32, name);
|
||||||
@ -418,6 +414,10 @@ static int task_database_iterate_playlist_archive(
|
|||||||
return task_database_iterate_crc_lookup(
|
return task_database_iterate_crc_lookup(
|
||||||
db_state, db, db_state->archive_name);
|
db_state, db, db_state->archive_name);
|
||||||
|
|
||||||
|
strlcpy(userdata.archive_name, db_state->archive_name, sizeof(userdata.archive_name));
|
||||||
|
|
||||||
|
userdata.crc = db_state->crc;
|
||||||
|
|
||||||
if (file_archive_parse_file_iterate(&db->state,
|
if (file_archive_parse_file_iterate(&db->state,
|
||||||
&returnerr, name, NULL, archive_compare_crc32,
|
&returnerr, name, NULL, archive_compare_crc32,
|
||||||
&userdata))
|
&userdata))
|
||||||
|
@ -25,24 +25,11 @@
|
|||||||
#include "../verbosity.h"
|
#include "../verbosity.h"
|
||||||
#include "../msg_hash.h"
|
#include "../msg_hash.h"
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char *source_file;
|
|
||||||
char *subdir;
|
|
||||||
char *target_dir;
|
|
||||||
char *target_file;
|
|
||||||
char *valid_ext;
|
|
||||||
|
|
||||||
char *callback_error;
|
|
||||||
|
|
||||||
file_archive_transfer_t archive;
|
|
||||||
} decompress_state_t;
|
|
||||||
|
|
||||||
static int file_decompressed_target_file(const char *name,
|
static int file_decompressed_target_file(const char *name,
|
||||||
const char *valid_exts,
|
const char *valid_exts,
|
||||||
const uint8_t *cdata,
|
const uint8_t *cdata,
|
||||||
unsigned cmode, uint32_t csize, uint32_t size,
|
unsigned cmode, uint32_t csize, uint32_t size,
|
||||||
uint32_t crc32, void *userdata)
|
uint32_t crc32, struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
/* TODO/FIXME */
|
/* TODO/FIXME */
|
||||||
return 0;
|
return 0;
|
||||||
@ -52,22 +39,21 @@ static int file_decompressed_subdir(const char *name,
|
|||||||
const char *valid_exts,
|
const char *valid_exts,
|
||||||
const uint8_t *cdata,
|
const uint8_t *cdata,
|
||||||
unsigned cmode, uint32_t csize,uint32_t size,
|
unsigned cmode, uint32_t csize,uint32_t size,
|
||||||
uint32_t crc32, void *userdata)
|
uint32_t crc32, struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
char path_dir[PATH_MAX_LENGTH] = {0};
|
char path_dir[PATH_MAX_LENGTH] = {0};
|
||||||
char path[PATH_MAX_LENGTH] = {0};
|
char path[PATH_MAX_LENGTH] = {0};
|
||||||
decompress_state_t *dec = (decompress_state_t*)userdata;
|
|
||||||
|
|
||||||
/* Ignore directories. */
|
/* Ignore directories. */
|
||||||
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
||||||
goto next_file;
|
goto next_file;
|
||||||
|
|
||||||
if (strstr(name, dec->subdir) != name)
|
if (strstr(name, userdata->dec.subdir) != name)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
name += strlen(dec->subdir) + 1;
|
name += strlen(userdata->dec.subdir) + 1;
|
||||||
|
|
||||||
fill_pathname_join(path, dec->target_dir, name, sizeof(path));
|
fill_pathname_join(path, userdata->dec.target_dir, name, sizeof(path));
|
||||||
fill_pathname_basedir(path_dir, path, sizeof(path_dir));
|
fill_pathname_basedir(path_dir, path, sizeof(path_dir));
|
||||||
|
|
||||||
/* Make directory */
|
/* Make directory */
|
||||||
@ -84,8 +70,8 @@ next_file:
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
dec->callback_error = (char*)malloc(PATH_MAX_LENGTH);
|
userdata->dec.callback_error = (char*)malloc(PATH_MAX_LENGTH);
|
||||||
snprintf(dec->callback_error,
|
snprintf(userdata->dec.callback_error,
|
||||||
PATH_MAX_LENGTH, "Failed to deflate %s.\n", path);
|
PATH_MAX_LENGTH, "Failed to deflate %s.\n", path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -93,10 +79,10 @@ error:
|
|||||||
|
|
||||||
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, struct archive_extract_userdata *userdata)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX_LENGTH] = {0};
|
char path[PATH_MAX_LENGTH] = {0};
|
||||||
decompress_state_t *dec = (decompress_state_t*)userdata;
|
decompress_state_t *dec = &userdata->dec;
|
||||||
|
|
||||||
/* Ignore directories. */
|
/* Ignore directories. */
|
||||||
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
||||||
@ -180,9 +166,10 @@ static void task_decompress_handler_target_file(retro_task_t *task)
|
|||||||
{
|
{
|
||||||
bool retdec;
|
bool retdec;
|
||||||
decompress_state_t *dec = (decompress_state_t*)task->state;
|
decompress_state_t *dec = (decompress_state_t*)task->state;
|
||||||
|
struct archive_extract_userdata userdata = {0};
|
||||||
int ret = file_archive_parse_file_iterate(&dec->archive,
|
int ret = file_archive_parse_file_iterate(&dec->archive,
|
||||||
&retdec, dec->source_file,
|
&retdec, dec->source_file,
|
||||||
dec->valid_ext, file_decompressed_target_file, dec);
|
dec->valid_ext, file_decompressed_target_file, &userdata);
|
||||||
|
|
||||||
task->progress = file_archive_parse_file_progress(&dec->archive);
|
task->progress = file_archive_parse_file_progress(&dec->archive);
|
||||||
|
|
||||||
@ -201,6 +188,8 @@ static void task_decompress_handler_subdir(retro_task_t *task)
|
|||||||
decompress_state_t *dec = (decompress_state_t*)task->state;
|
decompress_state_t *dec = (decompress_state_t*)task->state;
|
||||||
struct archive_extract_userdata userdata = {0};
|
struct archive_extract_userdata userdata = {0};
|
||||||
|
|
||||||
|
userdata.dec = *dec;
|
||||||
|
|
||||||
int ret = file_archive_parse_file_iterate(&dec->archive,
|
int ret = file_archive_parse_file_iterate(&dec->archive,
|
||||||
&retdec, dec->source_file,
|
&retdec, dec->source_file,
|
||||||
dec->valid_ext, file_decompressed_subdir, &userdata);
|
dec->valid_ext, file_decompressed_subdir, &userdata);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user