#include <json.h>
#include <pakfire/archive.h>
+#include <pakfire/compress.h>
#include <pakfire/constants.h>
#include <pakfire/logging.h>
#include <pakfire/package.h>
struct archive* reader;
// Payload
- struct archive* payload;
- FILE* fpayload;
- size_t installsize;
- unsigned int files;
+ struct pakfire_filelist* filelist;
struct pakfire_scriptlet** scriptlets;
unsigned int num_scriptlets;
};
-static int pakfire_packager_create_payload(struct pakfire_packager* p) {
- char path[] = PAKFIRE_TMP_DIR "/pakfire-payload.XXXXXX";
-
- p->payload = archive_write_new();
- if (!p->payload) {
- ERROR(p->pakfire, "archive_write_new() failed\n");
- return 1;
- }
-
- // Use the PAX format
- int r = archive_write_set_format_pax(p->payload);
- if (r) {
- ERROR(p->pakfire, "Could not set format to PAX: %s\n",
- archive_error_string(p->payload));
- return r;
- }
-
- // Create a new temporary file
- p->fpayload = pakfire_mktemp(path);
- if (!p->fpayload)
- return 1;
-
- // Unlink the file straight away
- unlink(path);
-
- // Write archive to file
- r = archive_write_open_FILE(p->payload, p->fpayload);
- if (r)
- return r;
-
- // Add a requirement for the cryptographic algorithms we are using
- pakfire_package_add_requires(p->pkg, "pakfire(Digest-SHA512)");
- pakfire_package_add_requires(p->pkg, "pakfire(Digest-SHA256)");
-
- return 0;
-}
-
static void pakfire_packager_free(struct pakfire_packager* packager) {
// Scriptlets
if (packager->scriptlets) {
free(packager->scriptlets);
}
- // Payload
- if (packager->payload)
- archive_write_free(packager->payload);
-
- if (packager->fpayload)
- fclose(packager->fpayload);
-
if (packager->reader)
archive_read_free(packager->reader);
+ if (packager->filelist)
+ pakfire_filelist_unref(packager->filelist);
pakfire_package_unref(packager->pkg);
pakfire_unref(packager->pakfire);
free(packager);
if (!p->reader)
goto ERROR;
- // Start payload
- r = pakfire_packager_create_payload(p);
+ // Create filelist
+ r = pakfire_filelist_create(&p->filelist, p->pakfire);
if (r)
goto ERROR;
+ // Add a requirement for the cryptographic algorithms we are using
+ pakfire_package_add_requires(p->pkg, "pakfire(Digest-SHA512)");
+ pakfire_package_add_requires(p->pkg, "pakfire(Digest-SHA256)");
+
*packager = p;
return 0;
return packager;
pakfire_packager_free(packager);
-
return NULL;
}
return r;
}
-static int pakfire_packager_copy_archive(struct pakfire_packager* packager,
- struct archive* a, FILE* f) {
- struct archive* payload = NULL;
- struct archive_entry* entry = NULL;
- int r;
-
- DEBUG(packager->pakfire, "Copying payload\n");
-
- // Reset fd to beginning of the file
- rewind(f);
-
- // Re-open the payload archive for reading
- payload = archive_read_new();
- if (!payload) {
- ERROR(packager->pakfire, "Could not create archive reader: %m\n");
- r = 1;
- goto ERROR;
- }
-
- // We expect a tar archive
- r = archive_read_support_format_tar(payload);
- if (r) {
- ERROR(packager->pakfire, "Could not add support for tar: %s\n",
- archive_error_string(payload));
- goto ERROR;
- }
-
- // Open the file handle
- r = archive_read_open_FILE(payload, f);
- if (r) {
- ERROR(packager->pakfire, "Could not open payload: %s\n",
- archive_error_string(payload));
- goto ERROR;
- }
-
- // Copy all files into our archive
- for (;;) {
- r = archive_read_next_header(payload, &entry);
-
- // End when we have reached the end of the archive
- if (r == ARCHIVE_EOF) {
- r = 0;
- break;
- }
-
- // Raise any other errors
- else if (r) {
- ERROR(packager->pakfire, "Could not read next header: %s\n",
- archive_error_string(payload));
- goto ERROR;
- }
-
- // Write the entry
- r = archive_write_header(a, entry);
- if (r) {
- ERROR(packager->pakfire, "Could not write entry: %s\n",
- archive_error_string(a));
- goto ERROR;
- }
-
- // Copy the data
- r = pakfire_archive_copy_data(packager->pakfire, payload, a);
- if (r)
- goto ERROR;
- }
-
- // Success
- r = 0;
-
-ERROR:
- if (payload)
- archive_read_free(payload);
-
- return r;
-}
-
static int pakfire_packager_write_scriptlet(struct pakfire_packager* packager,
struct archive* a, struct pakfire_scriptlet* scriptlet) {
char filename[PATH_MAX];
struct archive* a = NULL;
int r = 1;
- // Close the payload
- if (packager->payload) {
- r = archive_write_free(packager->payload);
- if (r) {
- ERROR(packager->pakfire, "Could not close payload: %s\n",
- archive_error_string(packager->payload));
- goto ERROR;
- }
- packager->payload = NULL;
- }
+ const char* nevra = pakfire_package_get_nevra(packager->pkg);
// Add requires feature markers
if (pakfire_package_has_rich_deps(packager->pkg))
pakfire_package_add_requires(packager->pkg, "pakfire(RichDependencies)");
+ const size_t installsize = pakfire_filelist_total_size(packager->filelist);
+
// Store total install size
- pakfire_package_set_installsize(packager->pkg, packager->installsize);
+ pakfire_package_set_installsize(packager->pkg, installsize);
// Dump package metadata
char* dump = pakfire_package_dump(packager->pkg, PAKFIRE_PKG_DUMP_LONG);
}
// Write the payload
- if (packager->files) {
- r = pakfire_packager_copy_archive(packager, a, packager->fpayload);
- if (r) {
- ERROR(packager->pakfire, "Could not add payload to archive: %s\n",
- archive_error_string(a));
- goto ERROR;
- }
- }
+ r = pakfire_compress(packager->pakfire, a, packager->filelist, nevra,
+ PAKFIRE_COMPRESS_SHOW_THROUGHPUT, PAKFIRE_PACKAGER_DIGESTS);
// Success
r = 0;
}
int pakfire_packager_add_file(struct pakfire_packager* packager, struct pakfire_file* file) {
- struct archive_entry* entry = NULL;
- FILE* f = NULL;
- int r = 1;
-
// Check input
if (!file) {
errno = EINVAL;
return 1;
}
- // Payload has already been closed
- if (!packager->payload) {
- ERROR(packager->pakfire, "Payload has already been closed\n");
- errno = EPERM;
- return 1;
- }
-
// Fetch path
const char* path = pakfire_file_get_path(file);
- // Fetch filetype
- const mode_t filetype = pakfire_file_get_type(file);
-
// Files cannot have an empty path
if (!*path) {
ERROR(packager->pakfire, "Cannot add a file with an empty path\n");
pakfire_file_set_group(file, "root");
}
- // Open the file
- f = pakfire_file_open(file);
- if (!f)
- goto ERROR;
-
- // Add digests for regular files
- r = pakfire_file_compute_digests(file, PAKFIRE_PACKAGER_DIGESTS);
- if (r) {
- ERROR(packager->pakfire, "Could not compute digests: %m\n");
- goto ERROR;
- }
-
- // Generate file metadata into an archive entry
- entry = pakfire_file_archive_entry(file, PAKFIRE_PACKAGER_DIGESTS);
- if (!entry)
- goto ERROR;
-
- // Write the header
- r = archive_write_header(packager->payload, entry);
- if (r) {
- ERROR(packager->pakfire, "Error writing file header: %s\n",
- archive_error_string(packager->payload));
- goto ERROR;
- }
-
- // Copy the data of regular files
- if (filetype == S_IFREG) {
- // Copy the payload into the archive
- r = pakfire_archive_copy_data_from_file(packager->pakfire, packager->payload, f);
- if (r)
- goto ERROR;
- }
-
- // Increment installsize
- packager->installsize += pakfire_file_get_size(file);
-
- // Increment file counter
- packager->files++;
-
-ERROR:
- if (entry)
- archive_entry_free(entry);
- if (f)
- fclose(f);
-
- return r;
+ // Append the file to the filelist
+ return pakfire_filelist_append(packager->filelist, file);
}
int pakfire_packager_add(struct pakfire_packager* packager,