]> git.ipfire.org Git - pakfire.git/commitdiff
filelist: Add functions to search for files in directory
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 22 Mar 2021 16:44:21 +0000 (16:44 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 22 Mar 2021 16:44:21 +0000 (16:44 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/file.c
src/libpakfire/filelist.c
src/libpakfire/include/pakfire/file.h
src/libpakfire/include/pakfire/filelist.h

index 6326ccfebf27b2aaa84db13d4f534e751f69402d..87833249243b05c6d428dcc04f348f69be8ac785 100644 (file)
@@ -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);
+}
index 9596af05300be16ce2d14e759ef5f111f874703d..06c1804474f314ab433c7aacdbd7e7484a46468d 100644 (file)
 #############################################################################*/
 
 #include <errno.h>
+#include <fts.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include <archive.h>
+
 #include <pakfire/file.h>
 #include <pakfire/filelist.h>
+#include <pakfire/logging.h>
 #include <pakfire/pakfire.h>
 #include <pakfire/private.h>
 #include <pakfire/util.h>
@@ -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;
+}
index 79b4112e4afc9e89b98b04c3483b40fc60d66679..6eeb9c6f25e0486bc802a4137811fd37b62d9d7e 100644 (file)
@@ -66,10 +66,15 @@ PakfireFile pakfire_file_parse_from_file(const char* list, unsigned int format);
 
 #ifdef PAKFIRE_PRIVATE
 
+#include <stdio.h>
+
 #include <archive_entry.h>
 
+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 */
index d4c2c22c659a54d74fe0583f8807dfa49c3439b5..dfedccad868fbf76cc39231507d8e30dc8606f64 100644 (file)
@@ -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 */