libmpm

morphux C package management library
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/libmpm

commit 5613e27be5c5659c1393933dee4c19b95e352f43
parent ba78c4741fe3ee2d594eaf9b97b53136d4e040c1
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Tue,  9 May 2017 15:57:27 +0200

Add(Packer): Added function in order to decompress archive on disk:

Tests & Documentation TODO

Diffstat:
Minc/packer.h | 2++
Minc/packer_file.h | 2++
Msrc/packer.c | 79++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/packer_file.c | 27+++++++++++++++++++++++++++
Mtests/test_packer.c | 11+++++++++++
5 files changed, 120 insertions(+), 1 deletion(-)

diff --git a/inc/packer.h b/inc/packer.h @@ -163,4 +163,6 @@ bool packer_read_archive_in_memory(packer_t *ctx); */ bool packer_read_archive_header(packer_t *ctx); +bool packer_extract_archive(packer_t *ctx, const char *dir, char **output_dir); + #endif /* PACKER_H */ diff --git a/inc/packer_file.h b/inc/packer_file.h @@ -94,4 +94,6 @@ bool get_file_information(packer_file_t *file); */ packer_file_t *read_packer_file_from_binary(const char *content, off_t *ctr); +bool packer_file_to_disk(packer_file_t *file); + #endif /* PACKER_FILE_H */ diff --git a/src/packer.c b/src/packer.c @@ -742,7 +742,8 @@ static bool read_package_files(char *content, packer_t *ctx, off_t total_size) { packer_file_t *file = NULL; off_t ctr = 0; - while (total_size > ctr) { + while (total_size > ctr) + { file = read_packer_file_from_binary(content, &ctr); if (file == NULL) goto error; @@ -804,3 +805,79 @@ bool packer_read_archive_header(packer_t *ctx) { free(archive); return ret; } + +static char *packer_create_directory_name(packer_t *ctx, char sep) +{ + char *out = NULL; + + out = malloc(strlen(ctx->header->package->name) + + strlen(ctx->header->package->version) + 2); + if (out == NULL) + return NULL; + + strncpy(out, ctx->header->package->name, strlen(ctx->header->package->name)); + out[strlen(ctx->header->package->name)] = sep; + strncpy(out + strlen(ctx->header->package->name) + 1, + ctx->header->package->version, strlen(ctx->header->package->version)); + out[strlen(ctx->header->package->name) + + strlen(ctx->header->package->version) + 1] = '\0'; + + return out; +} + +bool packer_extract_archive(packer_t *ctx, const char *dir, char **output_dir) { + packer_file_t *file = NULL; + int fd, t_ctr; + bool ret = false; + char *archive = NULL; + off_t size, ctr; + char old_pwd[PATH_MAX]; + + getcwd(old_pwd, sizeof(old_pwd)); + + if (ctx->type != PACKER_TYPE_ARCHIVE) + return false; + + fd = open(ctx->str, O_RDONLY); + if (fd == -1) + return false; + + archive = mpm_read_file_from_fd(fd); + size = mpm_get_file_size_from_fd(fd); + + if (!read_package_header(archive, ctx, &t_ctr)) + goto cleanup; + + ctr = t_ctr; + + if (chdir(dir) == -1) + { + goto cleanup; + } + + *output_dir = packer_create_directory_name(ctx, '-'); + + if (mkdir(*output_dir, S_IRWXU | S_IRWXG | S_IRWXO) == -1 && errno != EEXIST) + goto cleanup; + + chdir(*output_dir); + + while (size > ctr) + { + file = read_packer_file_from_binary(archive, &ctr); + if (file == NULL) + goto cleanup; + if (packer_file_to_disk(file) == false) + goto cleanup; + packer_file_free(file); + free(file); + } + + ret = true; + +cleanup: + chdir(old_pwd); + close(fd); + free(archive); + return ret; +} diff --git a/src/packer_file.c b/src/packer_file.c @@ -224,3 +224,30 @@ packer_file_t *read_packer_file_from_binary(const char *content, off_t *ctr) { } return file; } + +bool packer_file_to_disk(packer_file_t *file) { + char *tmp = NULL; + FILE *fd = NULL; + + for (tmp = file->fn + 1; *tmp; tmp++) + { + if (*tmp == '/') + { + *tmp = 0; + if (mkdir(file->fn, S_IRWXU) == -1 && errno != EEXIST) + { + *tmp = '/'; + return false; + } + *tmp = '/'; + } + } + + fd = fopen(file->fn, "w+"); + if (fd == NULL) + return false; + + fprintf(fd, "%s\n", file->content); + fclose(fd); + return true; +} diff --git a/tests/test_packer.c b/tests/test_packer.c @@ -512,6 +512,16 @@ TEST(packer_file_init) { return TEST_SUCCESS; } +TEST(packer_extract_archive_1) { + packer_t *ctx = packer_init_archive(PACKAGE_OUTPUT_FN); + char *output_dir = NULL; + + TEST_ASSERT(packer_extract_archive(ctx, "/tmp", &output_dir), "Wrong return"); + packer_free(ctx); + free(output_dir); + return TEST_SUCCESS; +} + TEST(packer_create_archive_cleanup) { unlink(PACKAGE_OUTPUT_FN); return TEST_SUCCESS; @@ -563,5 +573,6 @@ void register_test_packer(void) { reg_test("packer", packer_read_package_header_package); reg_test("packer", packer_read_package_header); reg_test("packer", packer_file_init); + reg_test("packer", packer_extract_archive_1); reg_test("packer", packer_create_archive_cleanup); }