struct pakfire_scriptlet** scriptlets;
size_t nscriptlets;
- // OpenSSL
- EVP_MD_CTX* mdctx;
-
int nrefs;
};
// Free all checksums
pakfire_archive_free_chksums(archive);
- // Release OpenSSL context
- if (archive->mdctx)
- EVP_MD_CTX_free(archive->mdctx);
-
if (archive->path)
free(archive->path);
return pakfire_parser_get(archive->parser, namespace, key);
}
-static int archive_copy_data(PakfireArchive archive, struct archive* in, struct archive* out,
- char** hexdigest) {
- int r;
-
- // Create or reset OpenSSL context
- if (archive->mdctx) {
- r = EVP_MD_CTX_reset(archive->mdctx);
- if (r != 1) {
- ERROR(archive->pakfire, "Could not reset EVP_MD_CTX: %s\n",
- ERR_error_string(ERR_get_error(), NULL));
- return 1;
- }
- } else {
- archive->mdctx = EVP_MD_CTX_new();
- }
-
- // Initialize digest
- r = EVP_DigestInit_ex(archive->mdctx, EVP_blake2s256(), NULL);
- if (r != 1) {
- ERROR(archive->pakfire, "Could not setup digest function: %s\n",
- ERR_error_string(ERR_get_error(), NULL));
- return 1;
- }
-
- const void* buffer;
- size_t size;
- off_t offset;
-
- for (;;) {
- // Read a block of data
- r = archive_read_data_block(in, &buffer, &size, &offset);
- if (r == ARCHIVE_EOF)
- break;
-
- if (r != ARCHIVE_OK) {
- ERROR(archive->pakfire, "Could not read data from archive: %s\n",
- archive_error_string(in));
- return 1;
- }
-
- // Update digest
- r = EVP_DigestUpdate(archive->mdctx, buffer, size);
- if (r != 1) {
- ERROR(archive->pakfire, "EVP_DigestUpdate failed: %s\n",
- ERR_error_string(ERR_get_error(), NULL));
- return 1;
- }
-
- // Write the data
- r = archive_write_data_block(out, buffer, size, offset);
- if (r != ARCHIVE_OK) {
- ERROR(archive->pakfire, "Could not write data to disk: %s\n",
- archive_error_string(out));
- return 1;
- }
- }
-
- char digest[EVP_MAX_MD_SIZE];
- size_t digest_length = 0;
-
- // Finalize the digest
- r = EVP_DigestFinal_ex(archive->mdctx, (unsigned char*)digest, (unsigned int*)&digest_length);
- if (r != 1) {
- ERROR(archive->pakfire, "%s\n", ERR_error_string(ERR_get_error(), NULL));
- return 1;
- }
-
- // Convert to hex
- *hexdigest = pakfire_hexlify(digest, digest_length);
-
- DEBUG(archive->pakfire, "Computed digest of %zu bytes: %s\n", digest_length, *hexdigest);
-
- return 0;
-}
-
static la_int64_t archive_user_lookup(void* data, const char* name, la_int64_t uid) {
Pakfire pakfire = (Pakfire)data;
ARCHIVE_EXTRACT_SPARSE |
ARCHIVE_EXTRACT_TIME |
ARCHIVE_EXTRACT_UNLINK |
- ARCHIVE_EXTRACT_XATTR;
+ ARCHIVE_EXTRACT_XATTR |
+ ARCHIVE_EXTRACT_SECURE_SYMLINKS;
archive_write_disk_set_options(ext, flags);
free(h);
}
- // Create file
- r = archive_write_header(ext, entry);
+ // Create file & payload
+ r = archive_read_extract2(a, entry, ext);
if (r != ARCHIVE_OK) {
ERROR(archive->pakfire, "Could not extract file /%s: %s\n",
archive_pathname, archive_error_string(ext));
+ pakfire_file_unref(file);
break;
}
- // Copy payload
- if (size > 0) {
- char* hexdigest = NULL;
-
- r = archive_copy_data(archive, a, ext, &hexdigest);
- if (r != ARCHIVE_OK)
- break;
-
- // Set checksum
- if (hexdigest) {
- pakfire_file_set_chksum(file, hexdigest);
- free(hexdigest);
- }
- }
-
// Append file to filelist
r = pakfire_filelist_append(archive->filelist, file);
if (r)
break;
pakfire_file_unref(file);
-
- // Commit to disk
- r = archive_write_finish_entry(ext);
- switch (r) {
- case ARCHIVE_OK:
- continue;
-
- // A retry of this action might be successful
- case ARCHIVE_RETRY:
- r = archive_write_finish_entry(ext);
- break;
-
- case ARCHIVE_WARN:
- DEBUG(archive->pakfire, "/%s: %s\n",
- archive_pathname, archive_error_string(ext));
- continue;
-
- case ARCHIVE_FAILED:
- ERROR(archive->pakfire, "/%s: %s\n",
- archive_pathname, archive_error_string(ext));
- break;
- }
-
- if (r != ARCHIVE_OK)
- break;
}
archive_write_close(ext);