update: better handling of the keep files

This commit is contained in:
ngn 2024-08-04 13:11:25 +03:00
parent b27e31c66c
commit d2d6679060
19 changed files with 128 additions and 43 deletions

View File

@ -12,7 +12,7 @@ int main(int argc, char *argv[]) {
int ret = EXIT_FAILURE; int ret = EXIT_FAILURE;
char pooldir[strlen(TEMP_DIR) + 10]; char pooldir[strlen(TEMP_DIR) + 10];
sprintf(pooldir, "%s/%s", TEMP_DIR, "pool"); sprintf(pooldir, "%s/%s", DATA_DIR, "pool");
if (argc != 4) { if (argc != 4) {
printf("usage: %s <package name> <pool name> <pool url>\n", argv[0]); printf("usage: %s <package name> <pool name> <pool url>\n", argv[0]);

View File

@ -17,11 +17,19 @@ int main(int argc, char *argv[]) {
return ret; return ret;
} }
char pooldir[strlen(TEMP_DIR) + 10];
sprintf(pooldir, "%s/%s", DATA_DIR, "pool");
if (!lm_ctx_init(&ctx, ROOT_DIR, TEMP_DIR, DATA_DIR)) { if (!lm_ctx_init(&ctx, ROOT_DIR, TEMP_DIR, DATA_DIR)) {
printf("failed to init the ctx: %s (%d)\n", lm_strerror(), lm_error()); printf("failed to init the ctx: %s (%d)\n", lm_strerror(), lm_error());
goto end; goto end;
} }
if (lm_ctx_pool_add(&ctx, argv[1], argv[2], pooldir) == NULL) {
printf("failed to add pool: %s (%d)\n", lm_strerror(), lm_error());
goto end;
}
lm_ctx_ping(&ctx, NULL, NULL); lm_ctx_ping(&ctx, NULL, NULL);
lm_ctx_sync(&ctx, true, NULL, NULL); lm_ctx_sync(&ctx, true, NULL, NULL);

View File

@ -49,7 +49,8 @@ typedef bool (*lm_ctx_serve_callback_t)(lm_pool_t *pool, lm_mptp_t *packet, stru
typedef bool (*lm_ctx_ping_callback_t)(lm_ctx_t *ctx, lm_pool_t *pool, bool status, void *data); typedef bool (*lm_ctx_ping_callback_t)(lm_ctx_t *ctx, lm_pool_t *pool, bool status, void *data);
typedef bool (*lm_ctx_remove_callback_t)( typedef bool (*lm_ctx_remove_callback_t)(
lm_ctx_t *ctx, lm_entry_t *pkg, char *file, size_t current, size_t total, void *data); lm_ctx_t *ctx, lm_entry_t *pkg, char *file, size_t current, size_t total, void *data);
typedef lm_ctx_remove_callback_t lm_ctx_check_callback_t; typedef bool (*lm_ctx_check_callback_t)(
lm_ctx_t *ctx, lm_entry_t *pkg, char *file, bool success, size_t current, size_t total, void *data);
/* ############### /* ###############
## ctx stuff ## ## ctx stuff ##
@ -89,7 +90,7 @@ bool lm_ctx_serve(
## temp directory fucntions ## ## temp directory fucntions ##
############################## */ ############################## */
char *lm_ctx_temp_dir(lm_ctx_t *ctx, char *dir); char *lm_ctx_temp_dir(lm_ctx_t *ctx, char *dir);
void lm_ctx_temp_clear(lm_ctx_t *ctx); bool lm_ctx_temp_clear(lm_ctx_t *ctx);
/* #################### /* ####################
## pool fucntions ## ## pool fucntions ##

View File

@ -142,6 +142,8 @@ typedef enum lm_error {
LM_ERR_NotDir = 140, LM_ERR_NotDir = 140,
LM_ERR_NoWrite = 141, LM_ERR_NoWrite = 141,
LM_ERR_PoolListBadDir = 142, LM_ERR_PoolListBadDir = 142,
LM_ERR_FileNotExist = 143,
LM_ERR_FileNotLink = 144,
} lm_error_t; } lm_error_t;
typedef struct lm_error_desc { typedef struct lm_error_desc {

View File

@ -23,7 +23,7 @@ bool can_write(char *path);
bool can_read(char *path); bool can_read(char *path);
bool is_file(char *path); bool is_file(char *path);
bool is_dir(char *path); bool is_dir(char *path);
bool exists(char *path); bool exists(char *path, struct stat *st);
bool is_empty(char *p); bool is_empty(char *p);
bool is_dir_empty(char *p); bool is_dir_empty(char *p);
bool rmrf(char *p); bool rmrf(char *p);

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-03 22:16+0300\n" "POT-Creation-Date: 2024-08-04 13:06+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -603,3 +603,13 @@ msgstr ""
#: src/error.c:161 #: src/error.c:161
msgid "specified list extraction directory is not accessible" msgid "specified list extraction directory is not accessible"
msgstr "" msgstr ""
#: src/error.c:162
#, c-format
msgid "file does not exist: %s"
msgstr ""
#: src/error.c:163
#, c-format
msgid "file is a symbolic link: %s"
msgstr ""

View File

@ -5,6 +5,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/stat.h>
bool lm_ctx_check(lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_check_callback_t callback, void *data){ bool lm_ctx_check(lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_check_callback_t callback, void *data){
if(NULL == ctx || NULL == entry){ if(NULL == ctx || NULL == entry){
@ -22,24 +23,37 @@ bool lm_ctx_check(lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_check_callback_t call
size_t rootlen = strlen(ctx->root), current = 0, total = 0; size_t rootlen = strlen(ctx->root), current = 0, total = 0;
char *path = NULL, *hash = NULL, *fhash = NULL; char *path = NULL, *hash = NULL, *fhash = NULL;
bool keep = false, ret = false; bool keep = false, ret = false, success = false;
struct stat st;
total = lm_database_files_count(ctx->db, entry); total = lm_database_files_count(ctx->db, entry);
while(lm_database_files_next(ctx->db, entry, &path, &hash, &keep)){ while(lm_database_files_next(ctx->db, entry, &path, &hash, &keep)){
char fp[rootlen+strlen(path)+10]; char fp[rootlen+strlen(path)+10];
join(fp, ctx->root, path); join(fp, ctx->root, path);
bzero(&st, sizeof(st));
success = false;
current++; current++;
pdebug(__func__, "(%d/%d) checking %s", current, total, fp); pdebug(__func__, "(%d/%d) checking %s", current, total, fp);
if(NULL != callback) if(!exists(fp, &st)){
if(!callback(ctx, entry, fp, current, total, data)) pdebug(__func__, "%s does not exist, check will fail", fp);
goto end; lm_error_set(LM_ERR_FileNotExist, fp);
goto next;
}
if(!exists(fp)){ if(S_ISLNK(st.st_mode)){
pdebug(__func__, "skipping %s because file does not exists", fp); pdebug(__func__, "%s seems to be a link, no hash verification to do", fp);
continue;
if(hash[0] != '\0'){
lm_error_set(LM_ERR_FileNotLink, fp);
goto end;
}
success = true;
goto next;
} }
if((fhash = get_md5(fp)) == NULL){ if((fhash = get_md5(fp)) == NULL){
@ -47,16 +61,25 @@ bool lm_ctx_check(lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_check_callback_t call
pdebug(__func__, "failed to get hash of %s: %s", fp, suberr); pdebug(__func__, "failed to get hash of %s: %s", fp, suberr);
lm_error_set(LM_ERR_FileHashFail, fp, suberr); lm_error_set(LM_ERR_FileHashFail, fp, suberr);
free(suberr); free(suberr);
goto end; goto next;
} }
if(!eq(fhash, hash)){ if(!eq(fhash, hash)){
lm_error_set(LM_ERR_FileHashNoMatch, fp); lm_error_set(LM_ERR_FileHashNoMatch, fp);
goto end; goto next;
} }
success = true;
next:
free(fhash); free(fhash);
fhash = NULL; fhash = NULL;
if(NULL != callback)
if(!callback(ctx, entry, fp, success, current, total, data))
goto end;
if(!success)
goto end;
} }
ret = true; ret = true;

View File

@ -136,14 +136,28 @@ bool __lm_ctx_extract_files(lm_ctx_t *ctx, lm_pkg_t *pkg, char *files, lm_ctx_in
current += archive_entry_size(entry); current += archive_entry_size(entry);
type = archive_entry_filetype(entry); type = archive_entry_filetype(entry);
if(type == AE_IFREG && !lm_database_files_contains(ctx->db, &pkg->data, entry_path)){ if(exists(entry_path, NULL) && lm_database_files_iskeep(ctx->db, entry_path)){
pdebug(__func__, "archive file not included in the database: %s (%s)", entry_path, pkg->data.name); pdebug(__func__, "not extracting %s, file is set as KEEP", entry_path);
continue; continue;
} }
if(exists(entry_path) && lm_database_files_iskeep(ctx->db, entry_path)){ switch (type) {
pdebug(__func__, "not extracting %s, file is set as KEEP", entry_path); case AE_IFLNK:
continue; if(!lm_database_files_add(ctx->db, &pkg->data, entry_path, "")){
char *suberr = lm_strerror_dup();
pdebug(__func__, "failed to add link to the database for %s: %s", pkg->data.name, suberr);
lm_error_set(LM_ERR_PkgFilesAddFail, entry_path, suberr);
free(suberr);
goto end;
}
break;
case AE_IFREG:
if(!lm_database_files_contains(ctx->db, &pkg->data, entry_path)){
pdebug(__func__, "archive file not included in the database: %s (%s)", entry_path, pkg->data.name);
goto next;
}
break;
} }
rc = archive_write_header(writer, entry); rc = archive_write_header(writer, entry);
@ -164,6 +178,9 @@ bool __lm_ctx_extract_files(lm_ctx_t *ctx, lm_pkg_t *pkg, char *files, lm_ctx_in
if(NULL != callback) if(NULL != callback)
if(!callback(ctx, pkg, entry_path, current, total, data)) if(!callback(ctx, pkg, entry_path, current, total, data))
goto end; goto end;
next:
continue;
} }
if (rc != ARCHIVE_EOF) { if (rc != ARCHIVE_EOF) {
@ -239,11 +256,11 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
join(install_file, ctx->temp, "INSTALL"); join(install_file, ctx->temp, "INSTALL");
join(files_archive, ctx->temp, "files.tar.gz"); join(files_archive, ctx->temp, "files.tar.gz");
if(!exists(data_file) || !is_file(data_file) || if(!exists(data_file, NULL) || !is_file(data_file) ||
!exists(hashes_file) || !is_file(hashes_file) || !exists(hashes_file, NULL) || !is_file(hashes_file) ||
!exists(changes_file) || !is_file(changes_file) || !exists(changes_file, NULL) || !is_file(changes_file) ||
!exists(install_file) || !is_file(install_file) || !exists(install_file, NULL) || !is_file(install_file) ||
!exists(files_archive) || !is_file(files_archive)){ !exists(files_archive, NULL) || !is_file(files_archive)){
lm_error_set(LM_ERR_PkgBadArchive); lm_error_set(LM_ERR_PkgBadArchive);
return false; return false;
} }
@ -297,7 +314,10 @@ bool lm_ctx_install(lm_ctx_t *ctx, lm_pkg_t *pkg, bool run_install, lm_ctx_insta
pdebug(__func__, "(%lu) %s => %s", line_len, file, hash); pdebug(__func__, "(%lu) %s => %s", line_len, file, hash);
lm_database_files_del_single(ctx->db, file); if(!lm_database_files_del_single(ctx->db, file)){
pdebug(__func__, "failed to remove file from the database for %s: %s", pkg->data.name, lm_error());
goto end;
}
if(!lm_database_files_add(ctx->db, &pkg->data, file, hash)){ if(!lm_database_files_add(ctx->db, &pkg->data, file, hash)){
char *suberr = lm_strerror_dup(); char *suberr = lm_strerror_dup();

View File

@ -63,7 +63,7 @@ bool lm_ctx_remove(lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_remove_callback_t ca
fpath = join_alloc(ctx->root, path); fpath = join_alloc(ctx->root, path);
pdebug(__func__, "removing file %s (%s)", fpath, entry->name); pdebug(__func__, "removing file %s (%s)", fpath, entry->name);
if(!exists(fpath)){ if(!exists(fpath, NULL)){
pdebug(__func__, "found file in database, but its not on the file system: %s", fpath); pdebug(__func__, "found file in database, but its not on the file system: %s", fpath);
goto next; goto next;
} }

View File

@ -100,7 +100,11 @@ size_t lm_ctx_sync(lm_ctx_t *ctx, bool do_update, lm_ctx_sync_callback_t callbac
} }
lm_ctx_temp_clear(ctx); lm_ctx_temp_clear(ctx);
tempdir = lm_ctx_temp_dir(ctx, "list_extracted");
if((tempdir = lm_ctx_temp_dir(ctx, "list_extracted")) == NULL){
pdebug(__func__, "(%s) failed to access list extract directory: %s", cur->name, lm_strerror());
goto next_list;
}
if(!do_update && !lm_pool_list_load(cur, tempdir)){ if(!do_update && !lm_pool_list_load(cur, tempdir)){
pdebug(__func__, "(%s) failed to load list: %s", cur->name, lm_strerror()); pdebug(__func__, "(%s) failed to load list: %s", cur->name, lm_strerror());

View File

@ -27,12 +27,19 @@ char *lm_ctx_temp_dir(lm_ctx_t *ctx, char *dir){
return strdup(td); return strdup(td);
} }
void lm_ctx_temp_clear(lm_ctx_t *ctx) { bool lm_ctx_temp_clear(lm_ctx_t *ctx) {
if(NULL == ctx->temp){ if(NULL == ctx->temp){
lm_error_set(LM_ERR_CtxTempNULL); lm_error_set(LM_ERR_CtxTempNULL);
return; return false;
}
rmrf(ctx->temp);
if(!mkdir_ifnot(ctx->temp)){
lm_error_set(LM_ERR_CtxTempFailMkdir);
return false;
} }
rmrf(ctx->temp); return true;
} }

View File

@ -58,7 +58,7 @@ char *lm_database_changes_get(lm_database_t *db, lm_entry_t *entry){
char *changes_path = malloc(strlen(db->dir)+sizeof(changes_file)); char *changes_path = malloc(strlen(db->dir)+sizeof(changes_file));
join(changes_path, db->dir, changes_file); join(changes_path, db->dir, changes_file);
if(!exists(changes_path)){ if(!exists(changes_path, NULL)){
lm_error_set(LM_ERR_DbChangesNotExists); lm_error_set(LM_ERR_DbChangesNotExists);
free(changes_path); free(changes_path);
return NULL; return NULL;

View File

@ -43,7 +43,7 @@ char *queries[] = {
"INSERT INTO files VALUES (?, ?, ?, ?)", "INSERT INTO files VALUES (?, ?, ?, ?)",
// QUERY_DELETE_FILE_ALL // QUERY_DELETE_FILE_ALL
"DELETE FROM files WHERE package = ? AND keep = 1", "DELETE FROM files WHERE package = ? AND keep = 0",
// QUERY_DELETE_FILE_SINGLE // QUERY_DELETE_FILE_SINGLE
"DELETE FROM files WHERE path = ?", "DELETE FROM files WHERE path = ?",
@ -66,12 +66,12 @@ lm_database_t *lm_database_new(char *path){
char *err = NULL; char *err = NULL;
bzero(db, sizeof(lm_database_t)); bzero(db, sizeof(lm_database_t));
if(exists(path) && (is_file(path) || !can_read(path) || !can_write(path))){ if(exists(path, NULL) && (is_file(path) || !can_read(path) || !can_write(path))){
lm_error_set(LM_ERR_DbCantAccess); lm_error_set(LM_ERR_DbCantAccess);
return NULL; return NULL;
} }
if(!exists(path) && !mkdir_ifnot(path)){ if(!exists(path, NULL) && !mkdir_ifnot(path)){
lm_error_set(LM_ERR_DbCantAccess); lm_error_set(LM_ERR_DbCantAccess);
return NULL; return NULL;
} }

View File

@ -159,6 +159,8 @@ void lm_error_set(lm_error_t code, ...) {
{.code = LM_ERR_NotDir, .desc = _("specified path is not a directory") }, {.code = LM_ERR_NotDir, .desc = _("specified path is not a directory") },
{.code = LM_ERR_FailMkdir, .desc = _("failed to create the specified directory") }, {.code = LM_ERR_FailMkdir, .desc = _("failed to create the specified directory") },
{.code = LM_ERR_PoolListBadDir, .desc = _("specified list extraction directory is not accessible") }, {.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") },
}; };
char *fmt = NULL; char *fmt = NULL;

View File

@ -25,7 +25,7 @@ bool lm_package_downloaded(lm_pkg_t *pkg){
return false; return false;
} }
if(!exists(pkg->archive) || !exists(pkg->signature)){ if(!exists(pkg->archive, NULL) || !exists(pkg->signature, NULL)){
lm_error_set(LM_ERR_PkgNotDownloaded); lm_error_set(LM_ERR_PkgNotDownloaded);
return false; return false;
} }

View File

@ -40,7 +40,7 @@ bool lm_pool_info_load(lm_pool_t *pool) {
return false; return false;
} }
if(!exists(pool->info_file) || !can_read(pool->info_file)){ if(!exists(pool->info_file, NULL) || !can_read(pool->info_file)){
lm_error_set(LM_ERR_PoolInfoCantRead); lm_error_set(LM_ERR_PoolInfoCantRead);
return false; return false;
} }

View File

@ -22,7 +22,7 @@ bool lm_pool_list_load(lm_pool_t *pool, char *dir){
return false; return false;
} }
if(!exists(pool->list_file) || !can_read(pool->list_file)){ if(!exists(pool->list_file, NULL) || !can_read(pool->list_file)){
lm_error_set(LM_ERR_PoolListCantRead); lm_error_set(LM_ERR_PoolListCantRead);
return false; return false;
} }

View File

@ -17,7 +17,7 @@ bool lm_pool_path_set_dir(lm_pool_t *pool, char *dir){
if(NULL == dir) if(NULL == dir)
return true; return true;
if(exists(dir) && (is_file(dir) || !can_read(dir) || !can_write(dir))){ if(exists(dir, NULL) && (is_file(dir) || !can_read(dir) || !can_write(dir))){
lm_error_set(LM_ERR_PoolBadDir); lm_error_set(LM_ERR_PoolBadDir);
return false; return false;
} }
@ -26,12 +26,12 @@ bool lm_pool_path_set_dir(lm_pool_t *pool, char *dir){
pool->info_file = join_alloc(dir, "INFO"); pool->info_file = join_alloc(dir, "INFO");
pool->list_file = join_alloc(dir, "LIST"); pool->list_file = join_alloc(dir, "LIST");
if(exists(pool->info_file) && (!is_file(pool->info_file) || !can_read(pool->info_file) || !can_write(pool->info_file))){ if(exists(pool->info_file, NULL) && (!is_file(pool->info_file) || !can_read(pool->info_file) || !can_write(pool->info_file))){
lm_error_set(LM_ERR_PoolBadPaths); lm_error_set(LM_ERR_PoolBadPaths);
return false; return false;
} }
if(exists(pool->list_file) && (!is_file(pool->list_file) || !can_read(pool->list_file) || !can_write(pool->list_file))){ if(exists(pool->list_file, NULL) && (!is_file(pool->list_file) || !can_read(pool->list_file) || !can_write(pool->list_file))){
lm_error_set(LM_ERR_PoolBadPaths); lm_error_set(LM_ERR_PoolBadPaths);
return false; return false;
} }

View File

@ -12,6 +12,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
void pdebug(const char *func, const char *fmt, ...) { void pdebug(const char *func, const char *fmt, ...) {
@ -220,9 +221,16 @@ end:
return ret; return ret;
} }
bool exists(char *path) { bool exists(char *path, struct stat *st) {
struct stat st; if (NULL == path)
return stat(path, &st) == 0; return false;
if (NULL == st) {
struct stat tmpst;
return lstat(path, &tmpst) == 0;
}
return lstat(path, st) == 0;
} }
bool is_file(char *path) { bool is_file(char *path) {