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));
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);
+}
#############################################################################*/
#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>
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;
+}