static void *file_archive_open(const char *path) { file_archive_file_data_t *data = (file_archive_file_data_t*)calloc(1, sizeof(*data)); if (!data) return NULL; data->fd = open(path, O_RDONLY); /* Failed to open archive. */ if (data->fd < 0) goto error; data->size = path_get_size(path); if (!data->size) return data; data->data = mmap(NULL, data->size, PROT_READ, MAP_SHARED, data->fd, 0); if (data->data == MAP_FAILED) { data->data = NULL; /* Failed to mmap() file */ goto error; } return data; error: file_archive_free(data); return NULL; }
int file_archive_parse_file_iterate( file_archive_transfer_t *state, bool *returnerr, const char *file, const char *valid_exts, file_archive_file_cb file_cb, void *userdata) { if (!state) return -1; switch (state->type) { case ZLIB_TRANSFER_NONE: break; case ZLIB_TRANSFER_INIT: if (file_archive_parse_file_init(state, file) == 0) state->type = ZLIB_TRANSFER_ITERATE; else state->type = ZLIB_TRANSFER_DEINIT_ERROR; break; case ZLIB_TRANSFER_ITERATE: { int ret = file_archive_parse_file_iterate_step(state, valid_exts, userdata, file_cb); if (ret != 1) state->type = ZLIB_TRANSFER_DEINIT; if (ret == -1) state->type = ZLIB_TRANSFER_DEINIT_ERROR; } break; case ZLIB_TRANSFER_DEINIT_ERROR: *returnerr = false; case ZLIB_TRANSFER_DEINIT: if (state->handle) file_archive_free(state->handle); state->handle = NULL; break; } if (state->type == ZLIB_TRANSFER_DEINIT || state->type == ZLIB_TRANSFER_DEINIT_ERROR) return -1; return 0; }
static void *file_archive_open(const char *path) { ssize_t ret = -1; bool read_from_file = false; file_archive_file_data_t *data = (file_archive_file_data_t*) calloc(1, sizeof(*data)); if (!data) return NULL; read_from_file = filestream_read_file(path, &data->data, &ret); /* Failed to open archive? */ if (!read_from_file || ret < 0) goto error; data->size = ret; return data; error: file_archive_free(data); return NULL; }
int file_archive_parse_file_iterate( file_archive_transfer_t *state, bool *returnerr, const char *file, const char *valid_exts, file_archive_file_cb file_cb, struct archive_extract_userdata *userdata) { if (!state) return -1; switch (state->type) { case ARCHIVE_TRANSFER_NONE: break; case ARCHIVE_TRANSFER_INIT: if (file_archive_parse_file_init(state, file) == 0) { if (userdata) { userdata->context = state->stream; strlcpy(userdata->archive_path, file, sizeof(userdata->archive_path)); } state->type = ARCHIVE_TRANSFER_ITERATE; } else state->type = ARCHIVE_TRANSFER_DEINIT_ERROR; break; case ARCHIVE_TRANSFER_ITERATE: if (file_archive_get_file_backend(file)) { const struct file_archive_file_backend *backend = file_archive_get_file_backend(file); int ret = backend->archive_parse_file_iterate_step(state, valid_exts, userdata, file_cb); if (ret != 1) state->type = ARCHIVE_TRANSFER_DEINIT; if (ret == -1) state->type = ARCHIVE_TRANSFER_DEINIT_ERROR; /* early return to prevent deinit from never firing */ return 0; } return -1; case ARCHIVE_TRANSFER_DEINIT_ERROR: *returnerr = false; case ARCHIVE_TRANSFER_DEINIT: if (state->handle) { file_archive_free(state->handle); state->handle = NULL; } if (state->stream && state->backend) { if (state->backend->stream_free) state->backend->stream_free(state->stream); if (state->stream) free(state->stream); state->stream = NULL; if (userdata) userdata->context = NULL; } break; } if ( state->type == ARCHIVE_TRANSFER_DEINIT || state->type == ARCHIVE_TRANSFER_DEINIT_ERROR) return -1; return 0; }