new: support for local package files
This commit is contained in:
parent
73a1f997e6
commit
1219501aaa
@ -124,3 +124,9 @@ bool lm_ctx_database_next(lm_ctx_t *ctx, lm_entry_t *entry); // load the n
|
||||
bool lm_ctx_database_next_free(lm_ctx_t *ctx, lm_entry_t *entry); // free the used next pointers
|
||||
char *lm_ctx_database_changes(
|
||||
lm_ctx_t *ctx, lm_entry_t *entry); // get changes file path for a package, FREE THE RETURNED POINTER
|
||||
|
||||
/* #######################
|
||||
## package fucntions ##
|
||||
####################### */
|
||||
bool lm_ctx_package_from(lm_ctx_t *ctx, lm_pkg_t *pkg, char *archive);
|
||||
void lm_ctx_package_from_free(lm_pkg_t *pkg);
|
||||
|
@ -144,6 +144,7 @@ typedef enum lm_error {
|
||||
LM_ERR_PoolListBadDir = 142,
|
||||
LM_ERR_FileNotExist = 143,
|
||||
LM_ERR_FileNotLink = 144,
|
||||
LM_ERR_ArchiveSetFail = 145,
|
||||
} lm_error_t;
|
||||
|
||||
typedef struct lm_error_desc {
|
||||
|
@ -8,6 +8,12 @@
|
||||
#define PKG_DATA_DEPENDS "depends"
|
||||
#define PKG_DATA_KEEPS "keeps"
|
||||
|
||||
#define DATA_FILE "DATA"
|
||||
#define HASHES_FILE "HASHES"
|
||||
#define CHANGES_FILE "CHANGES"
|
||||
#define INSTALL_FILE "INSTALL"
|
||||
#define FILES_ARCHIVE "files.tar.gz"
|
||||
|
||||
typedef struct lm_pkg_data {
|
||||
char *name;
|
||||
char *desc;
|
||||
@ -17,6 +23,14 @@ typedef struct lm_pkg_data {
|
||||
ssize_t size;
|
||||
} lm_pkg_data_t;
|
||||
|
||||
typedef struct lm_pkg_files {
|
||||
char *data_file;
|
||||
char *hashes_file;
|
||||
char *changes_file;
|
||||
char *install_file;
|
||||
char *files_archive;
|
||||
} lm_pkg_files_t;
|
||||
|
||||
typedef struct lm_pkg {
|
||||
struct lm_pkg_data data;
|
||||
struct lm_pool *pool;
|
||||
@ -51,3 +65,6 @@ void lm_package_data_keep_free(lm_pkg_data_t *data);
|
||||
bool lm_package_path_set_signature(lm_pkg_t *pkg, char *signature_path);
|
||||
bool lm_package_path_set_archive(lm_pkg_t *pkg, char *archive_path);
|
||||
bool lm_package_path_is_empty(lm_pkg_t *pkg);
|
||||
|
||||
lm_pkg_files_t *lm_package_extract(lm_pkg_t *pkg, char *target);
|
||||
void lm_package_extract_free(lm_pkg_files_t *files);
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-08-04 18:59+0300\n"
|
||||
"POT-Creation-Date: 2024-08-06 04:34+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -613,3 +613,7 @@ msgstr ""
|
||||
#, c-format
|
||||
msgid "file is a symbolic link: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/error.c:164
|
||||
msgid "failed to set the package archive"
|
||||
msgstr ""
|
||||
|
@ -210,7 +210,12 @@ end:
|
||||
}
|
||||
|
||||
bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_install_callback_t callback, void *data) {
|
||||
if(NULL == ctx->temp || NULL == pkg){
|
||||
if(NULL == ctx || NULL == pkg){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(NULL == ctx->temp){
|
||||
lm_error_set(LM_ERR_CtxTempNULL);
|
||||
return false;
|
||||
}
|
||||
@ -238,58 +243,41 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
|
||||
return false;
|
||||
}
|
||||
|
||||
lm_ctx_temp_clear(ctx);
|
||||
|
||||
if(!extract_archive(ctx->temp, pkg->archive))
|
||||
return false; // error set by function
|
||||
|
||||
size_t bufsize = strlen(ctx->temp) + 25;
|
||||
char data_file[bufsize], changes_file[bufsize], hashes_file[bufsize];
|
||||
char install_file[bufsize], files_archive[bufsize];
|
||||
lm_pkg_t temp;
|
||||
|
||||
lm_package_init(&temp);
|
||||
|
||||
join(data_file, ctx->temp, "DATA");
|
||||
join(hashes_file, ctx->temp, "HASHES");
|
||||
join(changes_file, ctx->temp, "CHANGES");
|
||||
join(install_file, ctx->temp, "INSTALL");
|
||||
join(files_archive, ctx->temp, "files.tar.gz");
|
||||
|
||||
if(!exists(data_file, NULL) || !is_file(data_file) ||
|
||||
!exists(hashes_file, NULL) || !is_file(hashes_file) ||
|
||||
!exists(changes_file, NULL) || !is_file(changes_file) ||
|
||||
!exists(install_file, NULL) || !is_file(install_file) ||
|
||||
!exists(files_archive, NULL) || !is_file(files_archive)){
|
||||
lm_error_set(LM_ERR_PkgBadArchive);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!lm_package_data_load(&temp.data, data_file))
|
||||
return false; // error set by function
|
||||
|
||||
if(!lm_package_is_same(&temp, pkg)){
|
||||
pdebug(__func__, "DATA file does not match with stored %s data", pkg->data.name);
|
||||
lm_error_set(LM_ERR_PkgDataNotMatch);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!lm_database_changes_update(ctx->db, &pkg->data, changes_file)){
|
||||
char *suberr = lm_strerror_dup();
|
||||
pdebug(__func__, "failed to update changes file for %s: %s", pkg->data.name, suberr);
|
||||
lm_error_set(LM_ERR_PkgChangesUpdateFail, suberr);
|
||||
return false;
|
||||
}
|
||||
|
||||
lm_pkg_files_t *files;
|
||||
char *line = NULL, *hash = NULL, *file = NULL;
|
||||
ssize_t line_len = 0, file_len = 0;
|
||||
FILE *hashes = NULL;
|
||||
bool ret = false;
|
||||
lm_pkg_t temp;
|
||||
|
||||
lm_ctx_temp_clear(ctx);
|
||||
lm_package_init(&temp);
|
||||
|
||||
if((hashes = fopen(hashes_file, "r")) == NULL){
|
||||
if((files = lm_package_extract(pkg, ctx->temp)) == NULL){
|
||||
pdebug(__func__, "failed to extract %s: %s", pkg->data.name, lm_strerror());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(!lm_package_data_load(&temp.data, files->data_file))
|
||||
goto end; // error set by function
|
||||
|
||||
if(!lm_package_is_same(&temp, pkg)){
|
||||
pdebug(__func__, "DATA file does not match with stored %s data", pkg->data.name);
|
||||
lm_error_set(LM_ERR_PkgDataNotMatch);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(!lm_database_changes_update(ctx->db, &pkg->data, files->changes_file)){
|
||||
char *suberr = lm_strerror_dup();
|
||||
pdebug(__func__, "failed to update changes file for %s: %s", pkg->data.name, suberr);
|
||||
lm_error_set(LM_ERR_PkgChangesUpdateFail, suberr);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if((hashes = fopen(files->hashes_file, "r")) == NULL){
|
||||
pdebug(__func__, "failed to open hash file for %s", pkg->data.name);
|
||||
lm_error_set(LM_ERR_PkgHashesOpenFail);
|
||||
return false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
while((line_len = getline(&line, (size_t*)&line_len, hashes)) > 0){
|
||||
@ -333,7 +321,7 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
|
||||
line_len = 0;
|
||||
}
|
||||
|
||||
if(!__lm_ctx_extract_files(ctx, pkg, files_archive, callback, data)){
|
||||
if(!__lm_ctx_extract_files(ctx, pkg, files->files_archive, callback, data)){
|
||||
char *suberr = lm_strerror_dup();
|
||||
pdebug(__func__, "failed to extract the files archive for %s: %s", pkg->data.name, suberr);
|
||||
lm_error_set(LM_ERR_PkgExtractFilesFail, suberr);
|
||||
@ -349,7 +337,7 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(run_install && !__lm_ctx_run_install(ctx->root, install_file)){
|
||||
if(run_install && !__lm_ctx_run_install(ctx->root, files->install_file)){
|
||||
char *suberr = lm_strerror_dup();
|
||||
pdebug(__func__, "failed to run install script: %s", lm_strerror());
|
||||
lm_error_set(LM_ERR_InstallRunFail, suberr);
|
||||
@ -357,7 +345,7 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(!run_install && !__lm_ctx_save_install(ctx, pkg, install_file)){
|
||||
if(!run_install && !__lm_ctx_save_install(ctx, pkg, files->install_file)){
|
||||
char *suberr = lm_strerror_dup();
|
||||
pdebug(__func__, "failed to save install script: %s", lm_strerror());
|
||||
lm_error_set(LM_ERR_InstallSaveFail, suberr);
|
||||
@ -371,6 +359,9 @@ end:
|
||||
|
||||
if(NULL != hashes)
|
||||
fclose(hashes);
|
||||
|
||||
lm_package_free(&temp);
|
||||
lm_package_extract_free(files);
|
||||
|
||||
if(!ret){
|
||||
lm_database_entry_del(ctx->db, &pkg->data);
|
||||
|
66
src/ctx/package.c
Normal file
66
src/ctx/package.c
Normal file
@ -0,0 +1,66 @@
|
||||
#include "../../include/package.h"
|
||||
#include "../../include/error.h"
|
||||
#include "../../include/util.h"
|
||||
#include "../../include/ctx.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
bool lm_ctx_package_from(lm_ctx_t *ctx, lm_pkg_t *pkg, char *archive){
|
||||
if(NULL == ctx || NULL == pkg || NULL == archive){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
// we should init the package pointer as soon as possible
|
||||
// so if the caller calls ..._from_free we can prevent
|
||||
// memory corruption
|
||||
lm_package_init(pkg);
|
||||
|
||||
if(NULL == ctx->temp) {
|
||||
lm_error_set(LM_ERR_CtxTempNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t archive_len = strlen(archive);
|
||||
char signature[archive_len+7];
|
||||
lm_pkg_files_t *files = NULL;
|
||||
bool ret = false;
|
||||
|
||||
sprintf(signature, "%s.sig", archive);
|
||||
|
||||
if(!lm_package_path_set_archive(pkg, archive) || !lm_package_path_set_signature(pkg, signature)){
|
||||
lm_error_set(LM_ERR_ArchiveSetFail);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!lm_ctx_temp_clear(ctx)){
|
||||
pdebug(__func__, "failed to clear the temp directory: %s", lm_strerror());
|
||||
return false; // error set by function
|
||||
}
|
||||
|
||||
if((files = lm_package_extract(pkg, ctx->temp)) == NULL){
|
||||
pdebug(__func__, "failed to extract the archive (%s): %s", archive, lm_strerror());
|
||||
return false; // error set by function
|
||||
}
|
||||
|
||||
if(!lm_package_data_load(&pkg->data, files->data_file)){
|
||||
pdebug(__func__, "failed to load the package data: %s", lm_strerror());
|
||||
goto end; // error set by function
|
||||
}
|
||||
|
||||
ret = true;
|
||||
end:
|
||||
lm_package_extract_free(files);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void lm_ctx_package_from_free(lm_pkg_t *pkg){
|
||||
if(NULL == pkg){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return;
|
||||
}
|
||||
|
||||
lm_package_free(pkg);
|
||||
}
|
@ -161,6 +161,7 @@ void lm_error_set(lm_error_t code, ...) {
|
||||
{.code = LM_ERR_PoolListBadDir, .desc = _("specified list extraction directory is not accessible") },
|
||||
{.code = LM_ERR_FileNotExist, .desc = _("file does not exist: %s") },
|
||||
{.code = LM_ERR_FileNotLink, .desc = _("file is a symbolic link: %s") },
|
||||
{.code = LM_ERR_ArchiveSetFail, .desc = _("failed to set the package archive") },
|
||||
};
|
||||
|
||||
char *fmt = NULL;
|
||||
|
71
src/package/extract.c
Normal file
71
src/package/extract.c
Normal file
@ -0,0 +1,71 @@
|
||||
#include "../../include/package.h"
|
||||
#include "../../include/error.h"
|
||||
#include "../../include/util.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool __lm_package_extract_check(char *file){
|
||||
if(!exists(file, NULL) || !is_file(file)){
|
||||
lm_error_set(LM_ERR_PkgBadArchive);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
lm_pkg_files_t *lm_package_extract(lm_pkg_t *pkg, char *target){
|
||||
if(NULL == pkg || NULL == target){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(lm_package_path_is_empty(pkg)){
|
||||
lm_error_set(LM_ERR_PkgPathsEmpty);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!extract_archive(target, pkg->archive))
|
||||
return NULL;
|
||||
|
||||
lm_pkg_files_t *files = malloc(sizeof(lm_pkg_files_t));
|
||||
bool ret = false;
|
||||
|
||||
bzero(files, sizeof(lm_pkg_files_t));
|
||||
|
||||
files->data_file = join_alloc(target, "DATA");
|
||||
files->hashes_file = join_alloc(target, "HASHES");
|
||||
files->changes_file = join_alloc(target, "CHANGES");
|
||||
files->install_file = join_alloc(target, "INSTALL");
|
||||
files->files_archive = join_alloc(target, "files.tar.gz");
|
||||
|
||||
if(!__lm_package_extract_check(files->data_file) ||
|
||||
!__lm_package_extract_check(files->hashes_file) ||
|
||||
!__lm_package_extract_check(files->changes_file) ||
|
||||
!__lm_package_extract_check(files->install_file) ||
|
||||
!__lm_package_extract_check(files->files_archive)){
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
end:
|
||||
if(!ret){
|
||||
lm_package_extract_free(files);
|
||||
files = NULL;
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
void lm_package_extract_free(lm_pkg_files_t *files){
|
||||
if(NULL == files)
|
||||
return;
|
||||
|
||||
free(files->data_file);
|
||||
free(files->hashes_file);
|
||||
free(files->changes_file);
|
||||
free(files->install_file);
|
||||
free(files->files_archive);
|
||||
|
||||
bzero(files, sizeof(lm_pkg_files_t));
|
||||
free(files);
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <dirent.h>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool lm_pool_list_load(lm_pool_t *pool, char *dir){
|
||||
@ -144,6 +145,8 @@ void lm_pool_list_free(lm_pool_t *pool){
|
||||
while(NULL != cur){
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
|
||||
lm_package_free(prev);
|
||||
free(prev);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user