return pakfire_string_set(transfer->path, path);
}
-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_digest_types md,
- const unsigned char* expected_digest,
- const size_t expected_digest_length,
- enum pakfire_transfer_flags flags) {
- struct pakfire_config* config = NULL;
- char filename[PATH_MAX];
- int r;
-
- DEBUG(downloader->pakfire, "Adding download of %s\n", url);
-
- // Reset baseurl it points to an empty string
- if (baseurl && !*baseurl)
- baseurl = NULL;
-
- // Do not allow relative URLs when no mirrors are set
- if (!pakfire_string_is_url(url) && !(mirrors || baseurl)) {
- ERROR(downloader->pakfire, "Relative URLs cannot be used without a baseurl and/or mirrorlist\n");
- errno = EINVAL;
- return NULL;
- }
-
- // Check if expected digest is set
- if (md) {
- if (!expected_digest || !expected_digest_length) {
- ERROR(downloader->pakfire, "Expected message digest or size is not set\n");
- errno = EINVAL;
- return NULL;
- }
- }
-
- // 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;
-
- // Keep a reference to downloader (without increasing the refcounter to avoid
- // circular connections)
- transfer->downloader = downloader;
-
- // Copy title
- if (title) {
- pakfire_string_set(transfer->title, title);
-
- // Or use the filename
- } else {
- r = pakfire_basename(filename, url);
- if (r)
- goto ERROR;
-
- if (*filename)
- pakfire_string_set(transfer->title, filename);
- }
-
- // Copy URL
- pakfire_string_set(transfer->url, url);
-
- // Copy path
- pakfire_string_set(transfer->path, path);
-
- // Open the desination file if we do not want a temporary file
- if (flags & PAKFIRE_TRANSFER_NOTEMP) {
- transfer->f = fopen(path, "w+");
- if (!transfer->f)
- goto ERROR;
- }
-
- // Copy baseurl
- if (baseurl)
- pakfire_string_set(transfer->baseurl, baseurl);
-
- // Keep a reference to the mirrorlist
- if (mirrors)
- transfer->mirrors = pakfire_mirrorlist_ref(mirrors);
-
- // Copy flags
- transfer->flags = flags;
-
- // Set message digest
- switch (md) {
- case PAKFIRE_DIGEST_SHA3_512:
- transfer->md = EVP_sha3_512();
- break;
-
- case PAKFIRE_DIGEST_SHA3_256:
- transfer->md = EVP_sha3_256();
- break;
-
- case PAKFIRE_DIGEST_BLAKE2B512:
- transfer->md = EVP_blake2b512();
- break;
-
- case PAKFIRE_DIGEST_BLAKE2S256:
- transfer->md = EVP_blake2s256();
- break;
-
- case PAKFIRE_DIGEST_SHA2_512:
- transfer->md = EVP_sha512();
- break;
-
- case PAKFIRE_DIGEST_SHA2_256:
- transfer->md = EVP_sha256();
- break;
-
- case PAKFIRE_DIGEST_UNDEFINED:
- break;
- }
-
- // Copy the expected digest
- if (transfer->md && expected_digest) {
- memcpy(transfer->expected_digest, expected_digest, expected_digest_length);
- transfer->expected_digest_length = expected_digest_length;
- }
-
- // Allocate handle
- transfer->handle = curl_easy_init();
- if (!transfer->handle)
- goto ERROR;
-
- // Fetch global configuration
- config = pakfire_get_config(downloader->pakfire);
-
- // Set global configuration
- if (config) {
- const char* proxy = pakfire_config_get(config, "general", "proxy", NULL);
- if (proxy) {
- curl_easy_setopt(transfer->handle, CURLOPT_PROXY, proxy);
- }
-
- pakfire_config_unref(config);
- }
-
- // Be a good net citizen and set a user agent
- curl_easy_setopt(transfer->handle, CURLOPT_USERAGENT, PACKAGE_NAME "/" PACKAGE_VERSION);
-
- // Enable logging/debugging
- curl_easy_setopt(transfer->handle, CURLOPT_VERBOSE, 1L);
-
-#ifdef ENABLE_DEBUG
- curl_easy_setopt(transfer->handle, CURLOPT_DEBUGFUNCTION, debug_callback);
- curl_easy_setopt(transfer->handle, CURLOPT_DEBUGDATA, downloader->pakfire);
-#endif
-
- // Limit protocols to HTTPS, HTTP, FTP and FILE
- curl_easy_setopt(transfer->handle, CURLOPT_PROTOCOLS_STR, "HTTPS,HTTP,FTP,FILE");
-
- // Reference back to this transfer
- curl_easy_setopt(transfer->handle, CURLOPT_PRIVATE, transfer);
-
- // Follow any redirects
- curl_easy_setopt(transfer->handle, CURLOPT_FOLLOWLOCATION, 1);
-
- // Success
- return transfer;
-
-ERROR:
- pakfire_downloader_transfer_free(transfer);
-
- return NULL;
-}
-
static int pakfire_transfer_select_mirror(struct pakfire_downloader* downloader,
struct pakfire_transfer* transfer) {
// Choose the next mirror
return 0;
}
-/*
- This function performs one single transfer in blocking mode.
-*/
-static int pakfire_downloader_perform(
- struct pakfire_downloader* downloader, struct pakfire_transfer* transfer) {
- int r;
-
-AGAIN:
- // Prepare the transfer
- r = pakfire_downloader_transfer_prepare(downloader, transfer, NULL, 0);
- if (r)
- return r;
-
- // Perform the download
- r = curl_easy_perform(transfer->handle);
-
- // Handle result
- r = pakfire_transfer_done(downloader, transfer, r);
-
- // Try again?
- if (r == EAGAIN)
- goto AGAIN;
-
- return r;
-}
-
int pakfire_downloader_transfer_run(struct pakfire_transfer* transfer, int flags) {
struct pakfire_downloader* downloader = transfer->downloader;
int r;
return r;
}
-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_digest_types md,
- const unsigned 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, expected_digest, expected_digest_length, flags);
- if (!transfer)
- return 1;
-
- // Perform the download
- int r = pakfire_downloader_perform(downloader, transfer);
- pakfire_downloader_transfer_free(transfer);
-
- return r;
-}
-
static size_t pakfire_downloader_total_downloadsize(struct pakfire_downloader* downloader) {
struct pakfire_transfer* transfer = NULL;
size_t size;