}
}
+ // Compose path for snapshot
+ r = pakfire_make_cache_path(build->pakfire, path, "%s", "snapshot.tar.zst");
+ if (r < 0) {
+ ERROR(build->pakfire, "Could not compose snapshot path: %m\n");
+ return 1;
+ }
+
// Tells us whether we need to (re-)create the snapshot
int snapshot_needs_update = 0;
- // Check if the user wants a snapshot extracted
+ // Extract snapshot
if (!pakfire_build_has_flag(build, PAKFIRE_BUILD_DISABLE_SNAPSHOT)) {
- // Extract snapshot
- r = pakfire_make_cache_path(build->pakfire, path, "%s", "snapshot.tar.zst");
- if (r < 0) {
- ERROR(build->pakfire, "Could not compose snapshot path: %m\n");
- return 1;
- }
-
// Open the snapshot
f = fopen(path, "r");
// Try restoring the snapshot
if (f) {
r = pakfire_snapshot_restore(build->pakfire, f);
- if (r) {
- fclose(f);
+ fclose(f);
+
+ // Exit on error
+ if (r)
return r;
- }
}
}
return NULL;
}
-int pakfire_snapshot_create(struct pakfire* pakfire, FILE* f) {
+int pakfire_snapshot_create(struct pakfire* pakfire, FILE* snapshot) {
+ struct pakfire_filelist* filelist = NULL;
+ struct archive* a = NULL;
int r = 1;
- if (!f) {
+ if (!snapshot) {
errno = EINVAL;
return 1;
}
+ // Create a new filelist
+ r = pakfire_filelist_create(&filelist, pakfire);
+ if (r)
+ goto ERROR;
+
const char* root = pakfire_get_path(pakfire);
INFO(pakfire, "Creating snapshot of %s...\n", root);
- struct archive* a = pakfire_snapshot_create_archive(pakfire, f);
- if (!a) {
- ERROR(pakfire, "Could not open archive for writing\n");
- return 1;
- }
-
- // Create disk reader
- struct archive* reader = pakfire_make_archive_disk_reader(pakfire, 1);
- if (!reader)
+ // Scan for all files
+ r = pakfire_filelist_scan(filelist, root, NULL, NULL);
+ if (r)
goto ERROR;
- // Open path
- r = archive_read_disk_open(reader, root);
- if (r) {
- ERROR(pakfire, "Could not open %s: %s\n", root, archive_error_string(reader));
+ const size_t size = pakfire_filelist_size(filelist);
+
+ // Check if we have any files
+ if (!size) {
+ ERROR(pakfire, "The snapshot is unexpectedly empty\n");
+ r = 1;
goto ERROR;
}
- struct archive_entry* entry = NULL;
- while (1) {
- r = archive_read_next_header(reader, &entry);
- if (r == ARCHIVE_EOF)
- break;
- else if (r == ARCHIVE_RETRY)
- continue;
- else if (r) {
- ERROR(pakfire, "Could not read next entry: %s\n", archive_error_string(reader));
- goto ERROR;
- }
-
- const char* full_path = archive_entry_pathname(entry);
+ // Sort the filelist in place
+ pakfire_filelist_sort(filelist);
- // Compute the relative path
- const char* path = pakfire_path_relpath(root, full_path);
- if (!path)
- continue;
+ a = pakfire_snapshot_create_archive(pakfire, snapshot);
+ if (!a) {
+ ERROR(pakfire, "Could not open archive for writing\n");
+ goto ERROR;
+ }
- // Skip mountpoints
- if (pakfire_is_mountpoint(pakfire, full_path)) {
- DEBUG(pakfire, "Skipping mountpoint %s...\n", path);
+ for (unsigned int i = 0; i < size; i++) {
+ struct pakfire_file* file = pakfire_filelist_get(filelist, i);
+ if (!file)
continue;
- }
- archive_read_disk_descend(reader);
+ FILE* f = NULL;
- // Reset path to relative path in archive
- archive_entry_set_pathname(entry, path);
+ // Make archive entry
+ struct archive_entry* entry = pakfire_file_archive_entry(file);
+ if (!entry) {
+ ERROR(pakfire, "Could not make archive entry from file: %m\n");
+ r = 1;
+ goto OUT;
+ }
// Write header
r = archive_write_header(a, entry);
if (r) {
ERROR(pakfire, "Could not write header: %s\n", archive_error_string(a));
- goto ERROR;
+ goto OUT;
}
// Copy payload
if (archive_entry_filetype(entry) == AE_IFREG) {
- r = pakfire_archive_copy_data(pakfire, reader, a);
+ f = pakfire_file_open(file);
+ if (!f) {
+ r = 1;
+ goto OUT;
+ }
+
+ r = pakfire_archive_copy_data_from_file(pakfire, a, f);
if (r) {
ERROR(pakfire, "Could not copy %s\n", archive_entry_pathname(entry));
- goto ERROR;
+ goto OUT;
}
}
// Write trailer
r = archive_write_finish_entry(a);
+ if (r)
+ goto OUT;
+
+OUT:
+ if (file)
+ pakfire_file_unref(file);
+ if (f)
+ fclose(f);
+
+ // Move on to ERROR
if (r)
goto ERROR;
}
r = 0;
ERROR:
- if (reader)
- archive_read_free(reader);
- archive_write_free(a);
+ if (filelist)
+ pakfire_filelist_unref(filelist);
+ if (a)
+ archive_write_free(a);
return r;
}