struct pakfire_scriptlet** scriptlets;
size_t nscriptlets;
+ // OpenSSL
+ EVP_MD_CTX* mdctx;
+
int nrefs;
};
static void pakfire_archive_free(PakfireArchive archive) {
DEBUG(archive->pakfire, "Releasing archive at %p\n", 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(Pakfire pakfire, struct archive* in, struct archive* out,
+static int archive_copy_data(PakfireArchive archive, struct archive* in, struct archive* out,
char** hexdigest) {
- EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
+ 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
- int r = EVP_DigestInit_ex(mdctx, EVP_blake2s256(), NULL);
+ r = EVP_DigestInit_ex(archive->mdctx, EVP_blake2s256(), NULL);
if (r != 1) {
- ERROR(pakfire, "Could not setup digest function: %s\n",
+ ERROR(archive->pakfire, "Could not setup digest function: %s\n",
ERR_error_string(ERR_get_error(), NULL));
- r = 1;
- goto ERROR;
+ return 1;
}
const void* buffer;
break;
if (r != ARCHIVE_OK) {
- ERROR(pakfire, "Could not read data from archive: %s\n",
+ ERROR(archive->pakfire, "Could not read data from archive: %s\n",
archive_error_string(in));
- goto ERROR;
+ return 1;
}
// Update digest
- r = EVP_DigestUpdate(mdctx, buffer, size);
+ r = EVP_DigestUpdate(archive->mdctx, buffer, size);
if (r != 1) {
- ERROR(pakfire, "EVP_DigestUpdate failed: %s\n",
+ ERROR(archive->pakfire, "EVP_DigestUpdate failed: %s\n",
ERR_error_string(ERR_get_error(), NULL));
- r = 1;
- goto ERROR;
+ return 1;
}
// Write the data
r = archive_write_data_block(out, buffer, size, offset);
if (r != ARCHIVE_OK) {
- ERROR(pakfire, "Could not write data to disk: %s\n",
+ ERROR(archive->pakfire, "Could not write data to disk: %s\n",
archive_error_string(out));
- goto ERROR;
+ return 1;
}
}
char digest[EVP_MAX_MD_SIZE];
- size_t digest_length;
+ size_t digest_length = 0;
// Finalize the digest
- r = EVP_DigestFinal_ex(mdctx, (unsigned char*)digest, (unsigned int*)&digest_length);
+ r = EVP_DigestFinal_ex(archive->mdctx, (unsigned char*)digest, (unsigned int*)&digest_length);
if (r != 1) {
- ERROR(pakfire, "%s\n", ERR_error_string(ERR_get_error(), NULL));
- goto ERROR;
+ ERROR(archive->pakfire, "%s\n", ERR_error_string(ERR_get_error(), NULL));
+ return 1;
}
// Convert to hex
*hexdigest = pakfire_hexlify(digest, digest_length);
- DEBUG(pakfire, "Computed digest of %zu bytes: %s\n", digest_length, *hexdigest);
+ DEBUG(archive->pakfire, "Computed digest of %zu bytes: %s\n", digest_length, *hexdigest);
- // Success
- r = 0;
-
-ERROR:
- if (mdctx)
- EVP_MD_CTX_free(mdctx);
-
- return r;
+ return 0;
}
-static int archive_extract(Pakfire pakfire, struct archive* a, const char* prefix) {
+static int archive_extract(PakfireArchive archive, struct archive* a, const char* prefix) {
struct archive_entry* entry;
int r;
char* pathname = pakfire_path_join(prefix, archive_pathname);
archive_entry_set_pathname(entry, pathname);
- DEBUG(pakfire, "Extracting %s (%zu bytes)\n", pathname, size);
+ DEBUG(archive->pakfire, "Extracting %s (%zu bytes)\n", pathname, size);
free(pathname);
// Update hardlink targets
// Create file
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK) {
- ERROR(pakfire, "Could not extract file /%s: %s\n",
+ ERROR(archive->pakfire, "Could not extract file /%s: %s\n",
archive_pathname, archive_error_string(ext));
break;
}
// Copy payload
if (size > 0) {
- r = archive_copy_data(pakfire, a, ext, &hexdigest);
+ r = archive_copy_data(archive, a, ext, &hexdigest);
if (r != ARCHIVE_OK)
break;
}
break;
case ARCHIVE_WARN:
- DEBUG(pakfire, "/%s: %s\n",
+ DEBUG(archive->pakfire, "/%s: %s\n",
archive_pathname, archive_error_string(ext));
continue;
case ARCHIVE_FAILED:
- ERROR(pakfire, "/%s: %s\n",
+ ERROR(archive->pakfire, "/%s: %s\n",
archive_pathname, archive_error_string(ext));
break;
}
if (use_payload)
pa = archive_open_payload(a);
- r = archive_extract(archive->pakfire, use_payload ? pa : a,
+ r = archive_extract(archive, use_payload ? pa : a,
prefix ? prefix : pakfire_get_path(archive->pakfire));
if (pa)