From: Michael Tremer Date: Mon, 22 Mar 2021 16:44:21 +0000 (+0000) Subject: filelist: Add functions to search for files in directory X-Git-Tag: 0.9.28~1285^2~488 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3a9677db19f3ca56ff1b4a12a5c9c52eaa666e59;p=pakfire.git filelist: Add functions to search for files in directory Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index 6326ccfeb..878332492 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -96,6 +96,36 @@ PAKFIRE_EXPORT int pakfire_file_copy_stat(PakfireFile file, struct stat* stat) { return 0; } +struct archive_entry* pakfire_file_archive_entry(PakfireFile file) { + struct archive_entry* entry = archive_entry_new(); + if (!entry) + return NULL; + + // Set path + archive_entry_copy_pathname(entry, pakfire_file_get_path(file)); + + // Set source path + archive_entry_copy_sourcepath(entry, file->abspath); + + // Set size + archive_entry_set_size(entry, pakfire_file_get_size(file)); + + // Set mode + archive_entry_set_mode(entry, pakfire_file_get_mode(file)); + + // Set user + archive_entry_set_uname(entry, pakfire_file_get_user(file)); + + // Set group + archive_entry_set_gname(entry, pakfire_file_get_group(file)); + + // Set times + archive_entry_set_ctime(entry, pakfire_file_get_ctime(file), 0); + archive_entry_set_mtime(entry, pakfire_file_get_mtime(file), 0); + + return entry; +} + int pakfire_file_copy_archive_entry(PakfireFile file, struct archive_entry* entry) { // Set path pakfire_file_set_path(file, archive_entry_pathname(entry)); @@ -233,3 +263,10 @@ PAKFIRE_EXPORT void pakfire_file_set_chksum(PakfireFile file, const char* chksum if (chksum) file->chksum = strdup(chksum); } + +FILE* pakfire_file_fopen(PakfireFile file, const char* mode) { + if (!*file->abspath) + return NULL; + + return fopen(file->abspath, mode); +} diff --git a/src/libpakfire/filelist.c b/src/libpakfire/filelist.c index 9596af053..06c180447 100644 --- a/src/libpakfire/filelist.c +++ b/src/libpakfire/filelist.c @@ -19,11 +19,15 @@ #############################################################################*/ #include +#include #include #include +#include + #include #include +#include #include #include #include @@ -318,3 +322,107 @@ ERROR: return 1; } + +static int pakfire_filelist_is_excluded(const char* path, const char** excludes) { + // If the exclude list is empty, nothing can be excluded + if (!excludes) + return 0; + + for (const char** exclude = excludes; *exclude; exclude++) { + if (pakfire_string_startswith(path, *exclude)) + return 1; + } + + // No match + return 0; +} + +int pakfire_filelist_scan(PakfireFilelist list, const char* root, + const char** includes, const char** excludes) { + struct archive* reader = archive_read_disk_new(); + if (!reader) + return 1; + + int r = 1; + + // XXX handle includes + + char* paths[] = { + (char*)root, NULL, + }; + + // Walk through the whole file system tree and find all matching files + FTS* tree = fts_open(paths, FTS_NOCHDIR, 0); + if (!tree) + goto ERROR; + + FTSENT* node; + while ((node = fts_read(tree))) { + // Ignore any directories in post order + if (node->fts_info & FTS_DP) + continue; + + // Compute the relative path + const char* path = pakfire_path_relpath(root, node->fts_path); + if (!path) + continue; + + // Skip excludes + if (pakfire_filelist_is_excluded(path, excludes)) { + DEBUG(list->pakfire, "Skipping %s...\n", path); + + r = fts_set(tree, node, FTS_SKIP); + if (r) + goto ERROR; + + continue; + } + + DEBUG(list->pakfire, "Processing %s...\n", path); + + struct archive_entry* entry = archive_entry_new(); + if (!entry) + goto ERROR; + + // Set path + archive_entry_set_pathname(entry, path); + + // Set source path + archive_entry_copy_sourcepath(entry, node->fts_path); + + r = archive_read_disk_entry_from_file(reader, entry, -1, node->fts_statp); + if (r) { + ERROR(list->pakfire, "Could not read from %s: %s\n", + node->fts_path, strerror(errno)); + goto ERROR; + } + + // Create file + PakfireFile file; + r = pakfire_file_create(&file, list->pakfire); + if (r) + goto ERROR; + + // Import attributes + r = pakfire_file_copy_archive_entry(file, entry); + if (r) { + pakfire_file_unref(file); + goto ERROR; + } + + // Append it to the list + r = pakfire_filelist_append(list, file); + if (r) { + pakfire_file_unref(file); + goto ERROR; + } + } + + // Success + r = 0; + +ERROR: + archive_read_free(reader); + + return r; +} diff --git a/src/libpakfire/include/pakfire/file.h b/src/libpakfire/include/pakfire/file.h index 79b4112e4..6eeb9c6f2 100644 --- a/src/libpakfire/include/pakfire/file.h +++ b/src/libpakfire/include/pakfire/file.h @@ -66,10 +66,15 @@ PakfireFile pakfire_file_parse_from_file(const char* list, unsigned int format); #ifdef PAKFIRE_PRIVATE +#include + #include +struct archive_entry* pakfire_file_archive_entry(PakfireFile file); int pakfire_file_copy_archive_entry(PakfireFile file, struct archive_entry* entry); +FILE* pakfire_file_fopen(PakfireFile file, const char* mode); + #endif #endif /* PAKFIRE_FILE_H */ diff --git a/src/libpakfire/include/pakfire/filelist.h b/src/libpakfire/include/pakfire/filelist.h index d4c2c22c6..dfedccad8 100644 --- a/src/libpakfire/include/pakfire/filelist.h +++ b/src/libpakfire/include/pakfire/filelist.h @@ -44,6 +44,9 @@ size_t pakfire_filelist_total_filesize(PakfireFilelist list); int pakfire_filelist_create_from_file(PakfireFilelist* list, Pakfire pakfire, const char* data, unsigned int format); +int pakfire_filelist_scan(PakfireFilelist list, const char* root, + const char** includes, const char** excludes); + #endif #endif /* PAKFIRE_FILELIST_H */