update: better handling of the keep files
This commit is contained in:
parent
b27e31c66c
commit
d2d6679060
@ -12,7 +12,7 @@ int main(int argc, char *argv[]) {
|
||||
int ret = EXIT_FAILURE;
|
||||
|
||||
char pooldir[strlen(TEMP_DIR) + 10];
|
||||
sprintf(pooldir, "%s/%s", TEMP_DIR, "pool");
|
||||
sprintf(pooldir, "%s/%s", DATA_DIR, "pool");
|
||||
|
||||
if (argc != 4) {
|
||||
printf("usage: %s <package name> <pool name> <pool url>\n", argv[0]);
|
||||
|
@ -17,11 +17,19 @@ int main(int argc, char *argv[]) {
|
||||
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)) {
|
||||
printf("failed to init the ctx: %s (%d)\n", lm_strerror(), lm_error());
|
||||
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_sync(&ctx, true, NULL, NULL);
|
||||
|
||||
|
@ -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_remove_callback_t)(
|
||||
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 ##
|
||||
@ -89,7 +90,7 @@ bool lm_ctx_serve(
|
||||
## temp directory fucntions ##
|
||||
############################## */
|
||||
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 ##
|
||||
|
@ -142,6 +142,8 @@ typedef enum lm_error {
|
||||
LM_ERR_NotDir = 140,
|
||||
LM_ERR_NoWrite = 141,
|
||||
LM_ERR_PoolListBadDir = 142,
|
||||
LM_ERR_FileNotExist = 143,
|
||||
LM_ERR_FileNotLink = 144,
|
||||
} lm_error_t;
|
||||
|
||||
typedef struct lm_error_desc {
|
||||
|
@ -23,7 +23,7 @@ bool can_write(char *path);
|
||||
bool can_read(char *path);
|
||||
bool is_file(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_dir_empty(char *p);
|
||||
bool rmrf(char *p);
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\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"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -603,3 +603,13 @@ msgstr ""
|
||||
#: src/error.c:161
|
||||
msgid "specified list extraction directory is not accessible"
|
||||
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 ""
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.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){
|
||||
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;
|
||||
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);
|
||||
|
||||
while(lm_database_files_next(ctx->db, entry, &path, &hash, &keep)){
|
||||
char fp[rootlen+strlen(path)+10];
|
||||
join(fp, ctx->root, path);
|
||||
bzero(&st, sizeof(st));
|
||||
|
||||
success = false;
|
||||
current++;
|
||||
|
||||
pdebug(__func__, "(%d/%d) checking %s", current, total, fp);
|
||||
|
||||
if(NULL != callback)
|
||||
if(!callback(ctx, entry, fp, current, total, data))
|
||||
goto end;
|
||||
if(!exists(fp, &st)){
|
||||
pdebug(__func__, "%s does not exist, check will fail", fp);
|
||||
lm_error_set(LM_ERR_FileNotExist, fp);
|
||||
goto next;
|
||||
}
|
||||
|
||||
if(!exists(fp)){
|
||||
pdebug(__func__, "skipping %s because file does not exists", fp);
|
||||
continue;
|
||||
if(S_ISLNK(st.st_mode)){
|
||||
pdebug(__func__, "%s seems to be a link, no hash verification to do", fp);
|
||||
|
||||
if(hash[0] != '\0'){
|
||||
lm_error_set(LM_ERR_FileNotLink, fp);
|
||||
goto end;
|
||||
}
|
||||
|
||||
success = true;
|
||||
goto next;
|
||||
}
|
||||
|
||||
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);
|
||||
lm_error_set(LM_ERR_FileHashFail, fp, suberr);
|
||||
free(suberr);
|
||||
goto end;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if(!eq(fhash, hash)){
|
||||
lm_error_set(LM_ERR_FileHashNoMatch, fp);
|
||||
goto end;
|
||||
goto next;
|
||||
}
|
||||
|
||||
success = true;
|
||||
next:
|
||||
free(fhash);
|
||||
fhash = NULL;
|
||||
|
||||
if(NULL != callback)
|
||||
if(!callback(ctx, entry, fp, success, current, total, data))
|
||||
goto end;
|
||||
|
||||
if(!success)
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
@ -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);
|
||||
type = archive_entry_filetype(entry);
|
||||
|
||||
if(type == AE_IFREG && !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);
|
||||
if(exists(entry_path, NULL) && lm_database_files_iskeep(ctx->db, entry_path)){
|
||||
pdebug(__func__, "not extracting %s, file is set as KEEP", entry_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(exists(entry_path) && lm_database_files_iskeep(ctx->db, entry_path)){
|
||||
pdebug(__func__, "not extracting %s, file is set as KEEP", entry_path);
|
||||
continue;
|
||||
switch (type) {
|
||||
case AE_IFLNK:
|
||||
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);
|
||||
@ -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(!callback(ctx, pkg, entry_path, current, total, data))
|
||||
goto end;
|
||||
|
||||
next:
|
||||
continue;
|
||||
}
|
||||
|
||||
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(files_archive, ctx->temp, "files.tar.gz");
|
||||
|
||||
if(!exists(data_file) || !is_file(data_file) ||
|
||||
!exists(hashes_file) || !is_file(hashes_file) ||
|
||||
!exists(changes_file) || !is_file(changes_file) ||
|
||||
!exists(install_file) || !is_file(install_file) ||
|
||||
!exists(files_archive) || !is_file(files_archive)){
|
||||
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;
|
||||
}
|
||||
@ -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);
|
||||
|
||||
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)){
|
||||
char *suberr = lm_strerror_dup();
|
||||
|
@ -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);
|
||||
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);
|
||||
goto next;
|
||||
}
|
||||
|
@ -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);
|
||||
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)){
|
||||
pdebug(__func__, "(%s) failed to load list: %s", cur->name, lm_strerror());
|
||||
|
@ -27,12 +27,19 @@ char *lm_ctx_temp_dir(lm_ctx_t *ctx, char *dir){
|
||||
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){
|
||||
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;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
join(changes_path, db->dir, changes_file);
|
||||
|
||||
if(!exists(changes_path)){
|
||||
if(!exists(changes_path, NULL)){
|
||||
lm_error_set(LM_ERR_DbChangesNotExists);
|
||||
free(changes_path);
|
||||
return NULL;
|
||||
|
@ -43,7 +43,7 @@ char *queries[] = {
|
||||
"INSERT INTO files VALUES (?, ?, ?, ?)",
|
||||
|
||||
// QUERY_DELETE_FILE_ALL
|
||||
"DELETE FROM files WHERE package = ? AND keep = 1",
|
||||
"DELETE FROM files WHERE package = ? AND keep = 0",
|
||||
|
||||
// QUERY_DELETE_FILE_SINGLE
|
||||
"DELETE FROM files WHERE path = ?",
|
||||
@ -66,12 +66,12 @@ lm_database_t *lm_database_new(char *path){
|
||||
char *err = NULL;
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!exists(path) && !mkdir_ifnot(path)){
|
||||
if(!exists(path, NULL) && !mkdir_ifnot(path)){
|
||||
lm_error_set(LM_ERR_DbCantAccess);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -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_FailMkdir, .desc = _("failed to create the specified directory") },
|
||||
{.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;
|
||||
|
@ -25,7 +25,7 @@ bool lm_package_downloaded(lm_pkg_t *pkg){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!exists(pkg->archive) || !exists(pkg->signature)){
|
||||
if(!exists(pkg->archive, NULL) || !exists(pkg->signature, NULL)){
|
||||
lm_error_set(LM_ERR_PkgNotDownloaded);
|
||||
return false;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ bool lm_pool_info_load(lm_pool_t *pool) {
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ bool lm_pool_list_load(lm_pool_t *pool, char *dir){
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ bool lm_pool_path_set_dir(lm_pool_t *pool, char *dir){
|
||||
if(NULL == dir)
|
||||
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);
|
||||
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->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);
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
14
src/util.c
14
src/util.c
@ -12,6 +12,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void pdebug(const char *func, const char *fmt, ...) {
|
||||
@ -220,9 +221,16 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool exists(char *path) {
|
||||
struct stat st;
|
||||
return stat(path, &st) == 0;
|
||||
bool exists(char *path, struct stat *st) {
|
||||
if (NULL == path)
|
||||
return false;
|
||||
|
||||
if (NULL == st) {
|
||||
struct stat tmpst;
|
||||
return lstat(path, &tmpst) == 0;
|
||||
}
|
||||
|
||||
return lstat(path, st) == 0;
|
||||
}
|
||||
|
||||
bool is_file(char *path) {
|
||||
|
Loading…
Reference in New Issue
Block a user