#include "reader.h" #include #include #include static b_result extract_file( struct ropkg_reader *pkg, const char *path_cstr, b_directory *dest) { b_path *path = b_path_create_from_cstr(path_cstr); if (!path) { return ROPKG_RESULT_ERR(NO_MEMORY); } b_path *dir_path = NULL; b_path_get_directory(path, &dir_path); if (!dir_path) { b_path_release(path); return ROPKG_RESULT_ERR(NO_MEMORY); } b_result result = B_RESULT_SUCCESS; if (b_path_length(dir_path) > 0) { b_directory *parent_dir; result = b_directory_open( dest, dir_path, B_DIRECTORY_OPEN_CREATE_INTERMEDIATE, &parent_dir); b_directory_release(parent_dir); } if (b_result_is_error(result)) { goto end; } b_file *dest_file = NULL; result = b_file_open( dest, path, B_FILE_WRITE_ONLY | B_FILE_CREATE | B_FILE_BINARY, &dest_file); if (b_result_is_error(result)) { goto end; } char data[] = "Hello"; size_t nr_written = 0; b_file_write(dest_file, 0, sizeof data, data, &nr_written); b_file_release(dest_file); end: b_path_release(path); b_path_release(dir_path); return result; } static b_result extract_subpackage( struct ropkg_reader *pkg, const char *name, b_directory *dest) { b_directory *dest_subdir; b_result result = b_directory_open( dest, B_RV_PATH(name), B_DIRECTORY_OPEN_CREATE, &dest_subdir); if (b_result_is_error(result)) { return result; } b_cstream_begin_compressed_section(pkg->r_stream, NULL); struct ropkg_reader *subpkg = NULL; enum ropkg_status status = ropkg_reader_open(pkg->r_stream, &subpkg); if (status != ROPKG_SUCCESS) { result = ROPKG_RESULT_STATUS(status); goto end; } while (!ropkg_reader_eof(subpkg)) { const struct ropkg_file_info *file = ropkg_reader_current_file(subpkg); result = extract_file(subpkg, file->f_filename, dest_subdir); if (b_result_is_error(result)) { break; } status = ropkg_reader_move_next(subpkg); if (status != ROPKG_SUCCESS) { result = ROPKG_RESULT_STATUS(status); break; } } end: b_cstream_end_compressed_section(pkg->r_stream, NULL, NULL); return result; } b_result ropkg_extract_metadata(struct ropkg_reader *pkg, b_directory *dest) { b_result result = B_RESULT_SUCCESS; while (!ropkg_reader_eof(pkg)) { const struct ropkg_file_info *file = ropkg_reader_current_file(pkg); int section = -1; if (!strncmp(file->f_filename, "meta.tar", 8)) { result = extract_subpackage(pkg, "meta", dest); } else if (!strncmp(file->f_filename, "control.tar", 11)) { result = extract_subpackage(pkg, "control", dest); } if (b_result_is_error(result)) { break; } enum ropkg_status status = ropkg_reader_move_next(pkg); if (status != ROPKG_SUCCESS) { result = ROPKG_RESULT_STATUS(status); break; } } return result; }