libmpm

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

commit a485eb808cbb90530531f67f246ce5a6b3251b2a
parent d329472b405128661d1061e5fb186bf87cfb0a0e
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Fri,  5 May 2017 19:26:51 +0200

Fix(Packer): Now separating packer and packer_file_t, for clarity

Diffstat:
Minc/packer.h | 10+---------
Ainc/packer_file.h | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/packer.c | 150-------------------------------------------------------------------------------
Asrc/packer_file.c | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 252 insertions(+), 159 deletions(-)

diff --git a/inc/packer.h b/inc/packer.h @@ -25,8 +25,7 @@ # include <sys/types.h> # include <dirent.h> # include <limits.h> -# include <sodium.h> -# include <zlib.h> +# include <packer_file.h> # define PACKER_DEF_CONF_FN "package.json" # define PACKER_DEF_EXT ".mpx" @@ -92,13 +91,6 @@ typedef struct packer_s { mlist_t *files; /*!< Files list, if it's an archive */ } packer_t; -typedef struct packer_file_s { - char *fn; /*!< Filename, with relative path (Ex: srcs/main.c ) */ - off_t file_size; /*!< File size, in bytes */ - char sum[crypto_hash_sha256_BYTES]; /*!< Sha256sum of the file */ - char *content; /*!< Actual content of the file */ -} packer_file_t; - /*! * \brief Allocate, fill and init a packer_t structure * diff --git a/inc/packer_file.h b/inc/packer_file.h @@ -0,0 +1,84 @@ +/*********************************** LICENSE **********************************\ +* Copyright 2017 Morphux * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +\******************************************************************************/ + +#ifndef PACKER_FILE_H +# define PACKER_FILE_H + +# include <libmpm.h> +# include <sodium.h> +# include <zlib.h> + +typedef struct packer_file_s { + char *fn; /*!< Filename, with relative path (Ex: srcs/main.c ) */ + off_t file_size; /*!< File size, in bytes */ + char sum[crypto_hash_sha256_BYTES]; /*!< Sha256sum of the file */ + char *content; /*!< Actual content of the file */ +} packer_file_t; + +/*! + * \brief Free a packer_file_t structure + * + * \param[in,out] magic Pointer to the struct + * + * \note Can be used as a list_free callback + * + * \return 1 on success, 0 on failure + */ +int packer_file_free(void *magic); + +/*! + * \brief Allocate and init a packer_file_t struct + * + * \param[in] file File name + * \param[in] dir Parent directory + * + * \return Freshly allocated structure on success, NULL on failure + */ +packer_file_t *packer_file_init(const char *file, const char *dir); + +/*! + * \brief Fill a packer_file_t list with a directory + * + * \param[in] dir_name Directory name + * \param[in,out] files Pointer to the head of a list + * \param[out] dirs Pointer to a list of directory + * + * This functions will read each member inside a directory. + * If it's a file, this functions will call get_file_information on it + * If it's a directory, the function will add the directory name (full path) + * in the dirst linked list + * + * \sa get_file_information + * \return true on success, false on failure + */ +bool read_files_from_dir(const char *dir_name, mlist_t **files, mlist_t **dirs); + +/*! + * \brief Get informations about a file + * + * \param[in,out] file Already filled packer_file_t structure + * + * This function will read the file specified in the member fn of the given + * structure, and get some informations about it: + * - His size + * - His content (compressed) + * - The Sha256sum of the content, uncompressed + * + * \return true on success, false on failure + */ +bool get_file_information(packer_file_t *file); + +#endif /* PACKER_FILE_H */ diff --git a/src/packer.c b/src/packer.c @@ -16,47 +16,6 @@ #include <packer.h> -static int packer_file_free(void *magic) { - packer_file_t *file = magic; - - if (file != NULL) - { - free(file->fn); - free(file->content); - } - return 1; -} - -MPX_STATIC packer_file_t *packer_file_init(const char *file, const char *dir) { - packer_file_t *ret = NULL; - - ret = calloc(1, sizeof(*ret)); - if (ret == NULL) - return NULL; - - ret->fn = malloc(strlen(file) + strlen(dir) + 1); - - if (ret->fn == NULL) - { - free(ret); - return NULL; - } - - if (strcpy(ret->fn, dir) == NULL) - goto error; - - if (strcat(ret->fn, file) == NULL) - goto error; - - ret->sum[0] = 0; - - return ret; - -error: - packer_file_free(ret); - free(ret); - return NULL; -} MPX_STATIC packer_t *packer_init(const char *str) { packer_t *ret; @@ -77,7 +36,6 @@ MPX_STATIC packer_t *packer_init(const char *str) { cleanup: free(ret); return NULL; - } MPX_STATIC packer_header_package_t *packer_header_package_init(void) { @@ -509,114 +467,6 @@ MPX_STATIC void write_package_header(FILE *fd, packer_t *ctx) { } } - -static bool get_file_information(packer_file_t *file) { - z_stream stream; - char *file_content = NULL; - char *chunk = NULL; - off_t file_size; - - file_size = mpm_get_file_size_from_fn(file->fn); - file_content = mpm_read_file_from_fn(file->fn); - if (file_content == NULL) - { - file->file_size = 0; - file->content = NULL; - return true; - } - - crypto_hash_sha256((unsigned char *)file->sum, - (const unsigned char *)file_content, - file_size); - - chunk = malloc(file_size); - if (chunk == NULL) - { - free(file_content); - return false; - } - - /* Compress file */ - stream.zalloc = NULL; - stream.zfree = NULL; - stream.opaque = NULL; - stream.avail_in = file_size; - stream.next_in = (Bytef *)file_content; - stream.avail_out = file_size; - stream.next_out = (Bytef *)chunk; - - deflateInit(&stream, Z_BEST_COMPRESSION); - deflate(&stream, Z_FINISH); - deflateEnd(&stream); - - file->file_size = stream.total_out; - file->content = malloc(file->file_size); - if (file->content == NULL) - { - free(file_content); - free(chunk); - return false; - } - - memcpy(file->content, chunk, file->file_size); - - free(file_content); - free(chunk); - return true; -} - -static bool read_files_from_dir(const char *dir_name, mlist_t **files, mlist_t **dirs) { - DIR *dir = opendir(dir_name); - struct dirent *dinfo = NULL; - packer_file_t *file = NULL; - - /* Directory not here is okay */ - if (dir == NULL) - return true; - - while ((dinfo = readdir(dir))) - { - if (strlen(dinfo->d_name) > 0 && dinfo->d_name[0] == '.') - continue ; - - if (dinfo->d_type == DT_DIR) - { - size_t tmp = strlen(dinfo->d_name); - - dinfo->d_name[tmp] = '/'; - dinfo->d_name[tmp + 1] = '\0'; - } - - file = packer_file_init(dinfo->d_name, dir_name); - if (file == NULL) - goto error; - - if (dinfo->d_type == DT_DIR) - { - list_add((*dirs), file->fn, strlen(file->fn) + 1); - packer_file_free(file); - } - else - { - if (get_file_information(file) == false) - { - packer_file_free(file); - free(file); - goto error; - } - list_add((*files), file, sizeof(*file)); - } - free(file); - } - - closedir(dir); - return true; - -error: - closedir(dir); - return false; -} - MPX_STATIC bool write_packer_sources(FILE *fd, packer_t *ctx, const char *dir_name) { mlist_t *files_list = NULL; mlist_t *dirs = NULL; diff --git a/src/packer_file.c b/src/packer_file.c @@ -0,0 +1,167 @@ +/*********************************** LICENSE **********************************\ +* Copyright 2017 Morphux * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +\******************************************************************************/ + +#include <packer_file.h> + +int packer_file_free(void *magic) { + packer_file_t *file = magic; + + if (file != NULL) + { + free(file->fn); + free(file->content); + } + return 1; +} + +packer_file_t *packer_file_init(const char *file, const char *dir) { + packer_file_t *ret = NULL; + + ret = calloc(1, sizeof(*ret)); + if (ret == NULL) + return NULL; + + ret->fn = malloc(strlen(file) + strlen(dir) + 1); + + if (ret->fn == NULL) + { + free(ret); + return NULL; + } + + if (strcpy(ret->fn, dir) == NULL) + goto error; + + if (strcat(ret->fn, file) == NULL) + goto error; + + ret->sum[0] = 0; + + return ret; + +error: + packer_file_free(ret); + free(ret); + return NULL; +} + +bool read_files_from_dir(const char *dir_name, mlist_t **files, mlist_t **dirs) { + DIR *dir = opendir(dir_name); + struct dirent *dinfo = NULL; + packer_file_t *file = NULL; + + /* Directory not here is okay */ + if (dir == NULL) + return true; + + while ((dinfo = readdir(dir))) + { + if (strlen(dinfo->d_name) > 0 && dinfo->d_name[0] == '.') + continue ; + + if (dinfo->d_type == DT_DIR) + { + size_t tmp = strlen(dinfo->d_name); + + dinfo->d_name[tmp] = '/'; + dinfo->d_name[tmp + 1] = '\0'; + } + + file = packer_file_init(dinfo->d_name, dir_name); + if (file == NULL) + goto error; + + if (dinfo->d_type == DT_DIR) + { + list_add((*dirs), file->fn, strlen(file->fn) + 1); + packer_file_free(file); + } + else + { + if (get_file_information(file) == false) + { + packer_file_free(file); + free(file); + goto error; + } + list_add((*files), file, sizeof(*file)); + } + free(file); + } + + closedir(dir); + return true; + +error: + closedir(dir); + return false; +} + +bool get_file_information(packer_file_t *file) { + z_stream stream; + char *file_content = NULL; + char *chunk = NULL; + off_t file_size; + + file_size = mpm_get_file_size_from_fn(file->fn); + file_content = mpm_read_file_from_fn(file->fn); + if (file_content == NULL) + { + file->file_size = 0; + file->content = NULL; + return true; + } + + crypto_hash_sha256((unsigned char *)file->sum, + (const unsigned char *)file_content, + file_size); + + chunk = malloc(file_size); + if (chunk == NULL) + { + free(file_content); + return false; + } + + /* Compress file */ + stream.zalloc = NULL; + stream.zfree = NULL; + stream.opaque = NULL; + stream.avail_in = file_size; + stream.next_in = (Bytef *)file_content; + stream.avail_out = file_size; + stream.next_out = (Bytef *)chunk; + + deflateInit(&stream, Z_BEST_COMPRESSION); + deflate(&stream, Z_FINISH); + deflateEnd(&stream); + + file->file_size = stream.total_out; + file->content = malloc(file->file_size); + if (file->content == NULL) + { + free(file_content); + free(chunk); + return false; + } + + memcpy(file->content, chunk, file->file_size); + + free(file_content); + free(chunk); + return true; +} +