// Download the file if it does not exist in the cache
if (access(cache_path, R_OK) != 0) {
r = pakfire_downloader_retrieve(downloader, BASEURL, mirrorlist,
- NULL, filename, cache_path, PAKFIRE_DOWNLOADER_MD_NONE, 0);
+ NULL, filename, cache_path, PAKFIRE_DOWNLOADER_MD_NONE, NULL, 0, 0);
if (r)
return r;
}
const EVP_MD* md;
unsigned char computed_digest[EVP_MAX_MD_SIZE];
unsigned int computed_digest_length;
+ unsigned char expected_digest[EVP_MAX_MD_SIZE];
+ unsigned int expected_digest_length;
// Mirrors
char baseurl[PATH_MAX];
static struct pakfire_transfer* pakfire_downloader_create_transfer(
struct pakfire_downloader* downloader, const char* baseurl, struct pakfire_mirrorlist* mirrors,
const char* title, const char* url, const char* path,
- enum pakfire_downloader_message_digest md, enum pakfire_transfer_flags flags) {
+ enum pakfire_downloader_message_digest md, const char* expected_digest, const size_t expected_digest_length,
+ enum pakfire_transfer_flags flags) {
struct pakfire_config* config = NULL;
DEBUG(downloader->pakfire, "Adding download of %s\n", url);
return NULL;
}
+ // Check if expected digest is set
+ switch (md) {
+ case PAKFIRE_DOWNLOADER_MD_NONE:
+ break;
+
+ default:
+ if (!expected_digest || !expected_digest_length) {
+ ERROR(downloader->pakfire, "Expected message digest or size is not set\n");
+ errno = EINVAL;
+ return NULL;
+ }
+ break;
+ }
+
+ // Expected digest length cannot be too long
+ if (expected_digest_length > EVP_MAX_MD_SIZE) {
+ ERROR(downloader->pakfire, "Digest length is too long\n");
+ errno = EMSGSIZE;
+ return NULL;
+ }
+
struct pakfire_transfer* transfer = calloc(1, sizeof(*transfer));
if (!transfer)
return NULL;
break;
}
+ // Copy the expected digest
+ if (transfer->md && expected_digest)
+ memcpy(transfer->expected_digest, expected_digest, expected_digest_length);
+
// Allocate handle
transfer->handle = curl_easy_init();
if (!transfer->handle)
int pakfire_downloader_add_transfer(struct pakfire_downloader* downloader,
const char* baseurl, struct pakfire_mirrorlist* mirrors, const char* title,
const char* url, const char* path, enum pakfire_downloader_message_digest md,
+ const char* expected_digest, const size_t expected_digest_length,
enum pakfire_transfer_flags flags) {
struct pakfire_transfer* transfer = pakfire_downloader_create_transfer(
- downloader, baseurl, mirrors, title, url, path, md, flags);
+ downloader, baseurl, mirrors, title, url, path, md, expected_digest, expected_digest_length, flags);
if (!transfer)
return 1;
int pakfire_downloader_retrieve(struct pakfire_downloader* downloader,
const char* baseurl, struct pakfire_mirrorlist* mirrors, const char* title,
const char* url, const char* path, enum pakfire_downloader_message_digest md,
+ const char* expected_digest, const size_t expected_digest_length,
enum pakfire_transfer_flags flags) {
struct pakfire_transfer* transfer = pakfire_downloader_create_transfer(
- downloader, baseurl, mirrors, title, url, path, md, flags);
+ downloader, baseurl, mirrors, title, url, path, md, expected_digest, expected_digest_length, flags);
if (!transfer)
return 1;
int pakfire_downloader_retrieve(struct pakfire_downloader* downloader,
const char* baseurl, struct pakfire_mirrorlist* mirrors, const char* title,
const char* url, const char* path, enum pakfire_downloader_message_digest md,
+ const char* expected_digest, const size_t expected_digest_length,
enum pakfire_transfer_flags flags);
int pakfire_downloader_add_transfer(struct pakfire_downloader* downloader,
const char* baseurl, struct pakfire_mirrorlist* mirrors, const char* title,
const char* url, const char* path, enum pakfire_downloader_message_digest md,
+ const char* expected_digest, const size_t expected_digest_length,
enum pakfire_transfer_flags flags);
int pakfire_downloader_run(struct pakfire_downloader* downloader);
static int pakfire_repo_retrieve(struct pakfire_repo* repo, const char* title,
const char* url, const char* path, enum pakfire_downloader_message_digest md,
+ const char* expected_digest, const size_t expected_digest_length,
enum pakfire_transfer_flags flags) {
struct pakfire_downloader* downloader;
int r = pakfire_downloader_create(&downloader, repo->pakfire);
// Retrieve the database file
r = pakfire_downloader_retrieve(downloader, repo->appdata->baseurl, mirrorlist,
- title, url, path, md, flags);
+ title, url, path, md, expected_digest, expected_digest_length, flags);
if (mirrorlist)
pakfire_mirrorlist_unref(mirrorlist);
// Try to download the key
int r = pakfire_repo_retrieve(repo, NULL, url, path,
- PAKFIRE_DOWNLOADER_MD_NONE, PAKFIRE_TRANSFER_NOTEMP|PAKFIRE_TRANSFER_NOPROGRESS);
+ PAKFIRE_DOWNLOADER_MD_NONE, NULL, 0, PAKFIRE_TRANSFER_NOTEMP|PAKFIRE_TRANSFER_NOPROGRESS);
if (r)
goto ERROR;
pakfire_string_format(database_url, "repodata/%s", database);
return pakfire_repo_retrieve(repo, title, database_url, cache_path,
- PAKFIRE_DOWNLOADER_MD_NONE, 0);
+ PAKFIRE_DOWNLOADER_MD_NONE, NULL, 0, 0);
}
static int pakfire_repo_read_metadata(struct pakfire_repo* repo, const char* path, int refresh) {
return pakfire_repo_retrieve(repo, NULL,
repo->appdata->mirrorlist_url, repo->appdata->mirrorlist,
- PAKFIRE_DOWNLOADER_MD_NONE, PAKFIRE_TRANSFER_NOPROGRESS);
+ PAKFIRE_DOWNLOADER_MD_NONE, NULL, 0, PAKFIRE_TRANSFER_NOPROGRESS);
}
static int pakfire_repo_refresh_metadata(struct pakfire_repo* repo, const int force) {
int r = pakfire_repo_retrieve(repo, NULL,
"repodata/repomd.json", repo->appdata->metadata, PAKFIRE_DOWNLOADER_MD_NONE,
- PAKFIRE_TRANSFER_NOPROGRESS);
+ NULL, 0, PAKFIRE_TRANSFER_NOPROGRESS);
if (r)
return r;
// Download the file
r = pakfire_downloader_retrieve(downloader, NULL, NULL, NULL,
- url, path, PAKFIRE_DOWNLOADER_MD_NONE, PAKFIRE_TRANSFER_NOTEMP);
+ url, path, PAKFIRE_DOWNLOADER_MD_NONE, NULL, 0, PAKFIRE_TRANSFER_NOTEMP);
if (r)
goto ERROR;
// Add transfer to downloader
r = pakfire_downloader_add_transfer(downloader, baseurl, mirrorlist,
- nevra, filename, path, PAKFIRE_DOWNLOADER_MD_NONE, 0);
+ nevra, filename, path, PAKFIRE_DOWNLOADER_MD_NONE, NULL, 0, 0);
ERROR:
if (mirrorlist)